SpringBoot集成测试
单元测试和集成测试的主要区别在于是否使用spring上下午ApplicationContext,如果只有@RunnerWith(SpringRunner.class)注解,则表示单元测试,而@SpringBootTest是集成测试。因为测试分片不需要上下文,所以测试分片是单元测试,有@JsonTest,@RestClientTest,@DataJpaTest,@WebMvcTest。
一. 测试一般程序(Service/DAO/Util类)
1. 在pom.xml中引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
<1> 如果使用IntelliJ IDEA,可以使用快捷键直接生成:
- Windows快捷键:Ctrl + Shift + T
- Mac快捷键:Commond + Shift + T
<2> 自己手动去创建
3. 编写测试类
<1> 在测试类上加入@RunWith(SpringRunner.class) 与@SpringBootTest 注解,
<2> 编写测试方法并添加@Test注解
二. 测试Controller类
1. 使用TestRestTemplate对象测试
<1> 在pom.xml中引入依赖(与上相同)
<2> 在测试类上加入@RunWith(SpringRunner.class) 与 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 注解
<3> 使用TestRestTemplate对象测试
2. 使用@WebMvcTest 注解测试
<1> 在pom.xml中引入依赖(与上相同)
<2> 在测试类上加入@RunWith(SpringRunner.class) 与 @WebMvcTest 注解
<3> 使用MockMvc对象测试
仍然测试UserController类
使用总结及相关注意点
1. @WebMvcTest 与 @SpringBootTest 注解不能一起使用,会报错
错误信息:found multiple declarations of @BootstrapWith
一个是:(value=class org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper)
一个是:(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper)
2. 使用@WebMvcTest注解进行测试时,只会加载在@WebMvcTest()中配置的bean,而@SpringBootTest注解会加载所有被Spring容器管理的bean
例如:@WebMvcTest(UserController.class) 只会加载UserController类
3. 如果使用MockMvc对象时,又希望会加载所有被Spring容器管理的bean,可以使用@AutoConfigureMockMvc注解,但是一般的Controller成都会引用到Service吧,怎么办呢,我们可以使用mockito框架的@MockBean注解进行模拟,改造后的代码如下:
@RunWith(SpringRunner.class) //使用@WebMvcTest只实例化Web层,而不是整个上下文。在具有多个Controller的应用程序中, // 甚至可以要求仅使用一个实例化,例如@WebMvcTest(UserController.class) @WebMvcTest(UserController.class) public class UserController03Test { @Autowired private MockMvc mockMvc; //模拟出一个userService @MockBean private UserService userService; @Test public void greetingShouldReturnMessageFromService() throws Exception { //模拟userService.findByUserId(1)的行为 when(userService.findByUserId(1)).thenReturn(new User(1,"张三")); String result = this.mockMvc.perform(get("/user/1")) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$.name").value("张三")) .andReturn().getResponse().getContentAsString(); System.out.println("result : " + result); } }
本文转自:https://www.jianshu.com/p/3a82791b9d3e?from=singlemessage