单元测试

SpringBoot 提供了 @SpringBootTest 注解,用于修饰单元测试用例类; 测试方法依然用  @Test 或 @ParameterizedTest 注解修饰

<!-- Spring Boot 单元测试的依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</denpendency>

其中 该依赖又依赖 JUnit 5.x, 所以会自动引入 JUnit 5的依赖,

一、 对控制器Controller 组件的测试

如下案例, 可以看到test成功,并且使用端口61358

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)     //代表运行测试用例时随机端口;  WebEnviroment.DEFIND_PORT 代表项目本身端口
@Slf4j
public class ExecTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void test01() {
        //测试test01 方法
        String resp = restTemplate.getForObject("/test/test01",String.class);
        log.info("方法返回值:" + resp);
        Assertions.assertEquals("欢迎访问第一个 Spring Boot 应用", resp);
    }

}

 

 

 

上面的测试案例中, 在运行单元测试时都会启动一个真实的 Web 服务器,如果不想启动真实的Web 服务器,可以使用 WebEnviroment.MOCK(默认为此配置) , 启动模拟服务器,

还可以获取ModelAndView 和常规返回值

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc       //启用MockMvc 的自动配置,Spring容器会自动配置一个 MockMvc Bean
public class MockEnvTest {

    @Autowired
    private MockMvc mockMvc;    //注入mockmvc bean

    @Test
    public void test01() throws Exception{
        var resp = mockMvc.perform(MockMvcRequestBuilders.get(new URI("/test/test01"))).andReturn().getResponse().getContentAsString();
        Assertions.assertEquals("欢迎访问第一个 Spring Boot 应用", resp);
    }

    @Test
    public void test02() throws Exception{
        var resp = mockMvc.perform(MockMvcRequestBuilders.get(new URI("/test/test02"))).andReturn().getModelAndView();
//        Assertions.assertEquals(Map.of("tip", "欢迎访问第一个 SpringBoot 应用"), resp.getModel());  Map.of 为jdk9 的快捷生成方法,目前jdk版本为8
        Map map = new HashMap();
        map.put("tip", "欢迎访问第一个 Spring Boot 应用");
        Assertions.assertEquals(map, resp.getModel());
        Assertions.assertEquals("hello", resp.getViewName());
    }
}

MockMvc 执行测试的方法只需要两步:

1、 使用MockMvcRequestBuilders 的 get()、post()、put()、patch()、delete()、options()、head() 等方法创建对应的请求, 如果需要设置请求参数、请求头等,则接着调用param()、header() 等方法

2、调用 MockMvc  对象的 perform() 方法执行请求; 返回值为 ResultActions, 可通过getResponse() 方法 或者 getModelAndView() 等获取到需要的响应

 

二、 测试业务组件

2.1 、 测试业务组件,不需要启动 web 服务器, 所以可将 WebEnviroment 属性设置为 WebEnviroment.NONE, 不启动web服务器

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class ServiceTest {

    @Autowired
    private TestService testService;

    @Test
    public void test01() {
        testService.getAllInfo().stream().forEach(System.out::println);
    }

    @ParameterizedTest
    @ValueSource(strings = {"张三"})
    public void test01(String name) {
        System.out.println(testService.getScoreByName(name));
    }

}

2.2、 使用模拟组件

  实际应用中,组件可能需要依赖其他的组件来访问数据库,或者调用第三方接口的服务,为了避免其他的因素影响单元测试效果,可以使用Mock 组件来模拟不稳定的组件,用于保证测试组件代码的健壮性; 如上面的 testService 组件实际使用testDao 来查询数据库,testDao可能尚未开发或者为测试通过,这时就需要我们先暂时模拟一个testDao.

    @Test
    public void test03() {

        //模拟 TestDao 的getAllInfo() 方法的返回值
        BDDMockito.given(this.testDao.getAllInfo()).willReturn(
                Arrays.asList("张三","李四")
        );
        List<String> list = testService.getAllInfo();

        Assertions.assertEquals(list.get(0), "张三");
        Assertions.assertEquals(list.get(1), "李四");

    }

 

 

注:后来遇到 springboot 2.1.8 版本还是需要配合添加 @RunWith(SpringRunner.class) 注解, 上述测试版本为 2.6.1 可直接使用 @SpringBootTest 即可。


posted @ 2021-12-08 23:31  长弓射大狗  阅读(78)  评论(0编辑  收藏  举报