【丁雪丰(译)】SpringBoot实战第四节:测试《读后感》

前言

作为程序开发者来说,本章的内容虽然讲述的是测试,但是个人认为测试环节对我们开发来说也很重要,我说的测试环节不是交给我们的测试人员,而是我们在项目实际开发中属于我们自测环节,我们在开发接口工作中,如果我们开发完一个功能,直接交给我们测试人员,我们没有系统的测试,这样会造成测试工作人员工作量加大,我们的反复改bug的任务加重,下面我针对本章内容谈一下自己的见解:


书中已经很好的给我们 一个答案,在编写应用程序时,明确目标的最佳方法就是写测试,确定应用程序的行为是否符合预期。这个测试用例在哪个环节写并不重要,通过这个问题,直接为我们引入了Spring相关测试的技术。
Spring的SpringJUnit4ClassRunner可以在基于JUnit的应用程序测试里加载Spring应用程序上下文。通过阅读书中内容,我们知道测试Springboot 应用程序时,Springboot除了拥有Spring的集成测试支持,还开启了自动配置和web服务器,并提供了不少实用的测试服务工具。

集成测试自动配置

在本小节主要向我们介绍,SpringFramework的核心工作是将所有组件编制在一起,构成一个应用程序,整个过程就是读取配置说明,在应用程序上下文里初始化Bean,将Bean注入依赖它们的其他Bean中,书中告诉我们对Spring应用程序进行集成测试时,让Spring遵照生产环境来组装测试目标Bean,我认为作者想告诉我们尽量接近生产,这样我们发布生产时就会降低出现事故的概率。

Spring集成测试demo

package com.zcw;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @ClassName : AddressServiceTests
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-04-28 12:16
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        classes = AddressServiceTests.class
)
public class AddressServiceTests {
    @Autowired
    private AddressServiceTests addressServiceTests;
    @Test
    public void a(){
        //TODO 相关业务代码
    }
}


根据上面的demo结合我们书中的知识点,说一下@RunWith的参数是SpringJUNIELit4ClassRunner.class,开启了Spring集成测试支持,同时@ContextConfiguration指定了如何加载应用程序上下文,这个注解里面填写的类,表明这个类里配置的Spring应用程序上下文。通过阅读我知道了,原来在SpringBoot项目中测试类与spring是不一样的,SpringBoot应用程序最终是由SpringApplication加载的,它不仅加载应用程序上下文,还会开启日志,加载外部属性比如:application.properties以及其他SpringBoot特性,如果这个地方使用spring的@ContextConfiguration则得不到这些特性。

测试Web应用程序

书中,告诉我们SpringMVC有一个优点:它的编程模型是围绕POJO展开的,所谓POJO就是java实体类,在POJO上添加注解,声明如何处理Web请求,这种编程模型不仅简单,还能让我们开发像对待应用程序中的其他组件一样对待这些控制器,
本节主要是进行说明spring的相关测试方法,也说了一下springboot测试方法,同时引导出Spring Mock MVC 能在一个近似真实的模拟Servlet容器里测试控制器,而不用实际启动应用服务器。
Web集成测试,在嵌入式Servlet容器(比如Tomcat或Jetty)里启动应用程序,在真正的应用服务器里执行测试,其中Spring Mock MVC 这个概念我是通过读本节内容我才知道,平时的开发测试我 一般使用postman或者main方法进行测试,首先这个SpringMockMVC 技术,我感觉挺好玩的,以后再进行测试的时候,可以通过这种方式进行测试一下,看看效果怎么样,

Spring MOCK MVC ----GET/POST请求:

package com.zcw;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;


import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 * @ClassName : MockMvcWebTests
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-04-28 13:22
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootConfiguration
@WebAppConfiguration
public class MockMvcWebTests {

    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;

    //设置MockMvc

    /**
     * @WebAppConfiguration注解声明,由SpringJUnit4ClassRunner创建的应用程序上下文应该是一个
     * WebApplicationContext,
     * 添加@Before表明它应该在测试方法之前执行,它将WebApplicationContext注入webAppContextSetup()方法,然后调用
     * build()产生了一个MockMvc实例,该实例赋给了一个实例变量,供测试方法使用
     */
    @Before
    public void setupMockMvc(){
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                .build();
    }
    //GET
    @Test
    public void homePage()throws Exception{
        mockMvc.perform(MockMvcRequestBuilders.get("/readingList"))
                .andExpect(status().isOk())
                .andExpect(MockMvcResultMatchers.view().name("readingList"))
                .andExpect(MockMvcResultMatchers.model().attributeExists("books"))
                .andExpect(MockMvcResultMatchers.model().attribute("books",Matchers.is(Matchers.empty())));
    }
    //POST
    public void postBook()throws Exception{
        mockMvc.perform(post("/readingList")
        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
        .param("title","BOOK TITLE")
                .param("author","BOOK AUTHOR")
                .param("isbn","1234567890")
                .param("description","DESCRIPTION"))
                .andExpect(status().is3xxRedirection())
                .andExpect(header().string("location","/readingList")
        );

    }
}


总结

其实本章还介绍了web安全的测试和Selenium测试,通过学习本章内容我收获最大的是测试框架的学习,同时也挺喜欢作者的这句话:“测试是开发高质量软件的重要一环,没有好的测试,你永远无法保证应用程序像期望的那样运行”。书中还说了单元测试的相关技术,喜欢探究的同学可以买本书可以好好的去学习,单元测试专注于单一组件或组件中的一个方法,此处并不一定要使用Spring,Spring提供了一些优势和技术----松耦合,依赖注入和接口驱动设计,这些都简化了单元测试的编写,说实话,通过本章的学习,加强了自己对测试环节重要性的认知,虽然书中只是简单的提供了一些测试的方法,但是我们在实际的项目开发中,整个项目进展的过程中,我们开发人员进行自测的重要性,想必工作过几年的同学,都会知道自测的重要性,活学活用吧。

原创文章 578 获赞 46 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_32370913/article/details/105809254