Spring Boot常用测试场景及分析
来源:互联网 发布:人工智能三年行动计划 编辑:程序博客网 时间:2024/06/05 11:20
本文用例基于Spring Boot+Kotlin实现。测试工程见:https://github.net/icarusliu/learn
1 常见测试场景
1.1 MVC测试单个Controller
可通过MockMvc进行特定MVC的请求测试处理;
要进行单个Controller的测试,需要使用@WebMvcTest来指定需要测试的Controller。
WebMvcTest及MockMvc的使用分析见后文。
import com.liuqi.learn.learninterceptor.controller.TestControllerimport org.junit.Testimport org.junit.runner.RunWithimport org.slf4j.LoggerFactoryimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.boot.test.autoconfigure.web.servlet.*import org.springframework.test.context.junit4.SpringRunnerimport org.springframework.test.web.servlet.MockMvcimport org.springframework.test.web.servlet.request.MockMvcRequestBuilders.getimport org.springframework.test.web.servlet.result.MockMvcResultMatchers.*@RunWith(SpringRunner::class)@WebMvcTest(TestController::class)class LearninterceptorApplicationTests { private val logger = LoggerFactory.getLogger(LearninterceptorApplicationTests::class.java) @Autowired private lateinit var mvc: MockMvc @Test fun testTestController() { mvc.perform(get("/test/test")).andExpect(status().isOk) .andExpect(content().string("test")); }}
1.2 MVC测试多个Controller
可以针对多个Controller进行测试,启动的是同一个容器;
不需要指定待测试的Controller;
也可以通过MockMvc来启动模拟请求;
示例如下:
@RunWith(SpringRunner::class)@SpringBootTest@AutoConfigureMockMvcclass TestLearninterceptorApplication { @Autowired private lateinit var mvc: MockMvc @Test fun testTest() { mvc.perform(MockMvcRequestBuilders.get("/test/test")).andExpect(MockMvcResultMatchers.status().isOk) .andExpect(MockMvcResultMatchers.content().string("test")); } @Test fun testTest1() { mvc.perform(MockMvcRequestBuilders.get("/test2/test")).andExpect(MockMvcResultMatchers.status().isOk) .andExpect(MockMvcResultMatchers.content().string("test2")); }}
1.3 测试打桩
可以通过MockBean进行测试打桩;
先看Service的定义:
@Serviceclass TestService { fun test(): String { return "test" }}
再看使用Service的Controller
@RestController@RequestMapping("/test2")class TestController2 { val logger = LoggerFactory.getLogger(TestController2::class.java) @Autowired private lateinit var testService: TestService @RequestMapping("/test") fun test(): String { logger.info("TestController2!") return "test2" } @RequestMapping("/service") fun testService(): String { return testService.test() }}
最后编写测试类:
@SpringBootTest@AutoConfigureMockMvcclass TestLearninterceptorApplication { @Autowired private lateinit var mvc: MockMvc @MockBean private lateinit var testService: TestService @Test fun testMock() { BDDMockito.given(this.testService.test()).willReturn("mockTest") mvc.perform(MockMvcRequestBuilders.get("/test/service")).andExpect(MockMvcResultMatchers.status().isOk) .andExpect(MockMvcResultMatchers.content().string("mockTest")) }}
1.4 集成测试
可以通过TestRestTemplate来进行集成测试;即在应用已经部署并在测试环境启动时,可以通过指定URL的方式进行测试用例的测试;
一般通过TestRestTemplate来进行测试(当然TestRestTemplate也可以进行单元测试,后文会进行详细说明);
import org.hamcrest.CoreMatchers.*import org.junit.Assertimport org.junit.Testimport org.springframework.boot.test.web.client.TestRestTemplateclass SITest { private val restTemplate: TestRestTemplate = TestRestTemplate() @Test fun testRest() { val body = restTemplate.getForEntity("http://localhost/test2/service", String::class.java).body Assert.assertThat(body, `is`("test")) }}
2 常见测试类
2.1 WebMvcTest
与SpringRunner一起使用,可测试指定的Controller;
注意在使用时需要指定待测试的Controller,可以指定多个待测试的Controller;
@WebMvcTest(*[TestController::class, TestController2::class])
WebMvcTest一般用于单元测试中测试Controller及其生效的Filter等场景;他会启动一个Spring容器,但只会加载其中部分MVC相关的内容,如Component、Service或者Repository等注解的Bean不会进行加载。
会加载的:Controller/ControllerAdvice/JsonComponent/Converter/Filter/WebMvcConfigurer/HandlerMethodArgumentResolver等; 因此如果待测试的Controller中使用了如Service等内容,需要打桩处理。
它所启动的Spring容器将会随测试用例的开始执行而启动,随所有测试用例执行完毕而停止;因此它适合本地开发环境的测试用例执行。
2.2 SpringBootTest
与SpringRunner一起使用,不需要指定Controller进行测试。
SpringBootTest会启动一个完整的Spring容器,这意味着它会加载所有Spring的内容;类似于将应用部署到了测试环境的Tomcat中;
与WebMvcTest一样,启动的只是一个临时的环境,随着测试用例的执行而启动,在所有测试用例执行完毕后这个环境会将会停止, 适合本地开发环境的测试用例执行。
2.3 TestRestTemplate
TestRestTemplate可使用在以下两个场景的测试:
2.3.1 远程测试
TestRestTemplate可用于Rest服务的远程测试;针对的是应用已经部署在测试环境应用服务器中的场景;
它可通过指定http://ip:port/…这种路径的方式来访问特定链接进行集成测试;
2.3.1 本地测试
TestRestTemplate也可用于本地开发环境的测试,与MockMvc类似,可通过指定相对路径的方式调用本地启动的SpringMVC来进行MVC测试;这种情况下也需要与SpringBootTest集成使用。
它与MockMVC不一样的是,MockMVC只能针对返回的内容进行测试,而TestRestTemplate可对Body、Headers等进行测试;
使用方式如下:
@RunWith(SpringRunner::class)@SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)class TestLearninterceptorApplication2 { @Autowired private lateinit var template: TestRestTemplate @Test fun test() { val body = template.getForEntity("/test2/service", String::class.java).body Assert.assertThat(body, CoreMatchers.`is`("test")) }// @TestConfiguration// class Config {// @Bean// fun restTemplateBuilder(): RestTemplateBuilder {// return RestTemplateBuilder()// }// }}
注意如果在SpringBootTest中不指定端口,则会报TestRestTemplate无法注入的错误。
TestRestTemplate的常用方法介绍如下:
部分场景下会返回ResponseEntity对象,该对象的常用方法如下:
2.4 MockMvc
MockMvc用于对本地启动的Spring环境进行测试,通过它的perform方法,它会模拟一个Http请求访问SpringMVC并返回ResultActions对象;
它一般要与SpringBootTest或者是WebMvcTest一起使用;
MockMvc的使用主要是使用其perform方法,这个方法返回类型是ResultActions对象;
这个对象包含以下方法:
andExpect方法中的Matcher可以使用MockMvcResultMatchers来进行构建,其可构建的Matcher包括:
三者结构使用的示例见1.1章节
2.5 MockBean
MockBean用于打桩,一般与BDDMockito结合使用。
MockBean本身功能较简单,主要是BDDMockito的使用。
2.6 BDDMockito
详细请参考此文
用于替换被打桩的Bean中的指定方法;
其包含的常用方法如下:
2.6.1 given
替换被打桩的对象的指定方法;
使用方式如:
val result = BDDMockito.given(this.testService.test())
其返回的类型为:BDDMyOngoingStubbing,其包含有以下常用方法:
- willAnswer: 根据传入参数定制返回结果;
- will: 与willAnswer类似
- willReturn: 定制直接的返回结果;
- willThrow: 定制将会抛出的异常
使用方法如:
val result = BDDMockito.given(this.testService.test())result.willReturn("test")
表示将这个方法的返回替换成test字符串。
2.6.2 then
请参考此文。
3 其它
3.1 WebMvcTest与SpringBootTest
这两个注解只能添加一个,如果混合使用会报错:
java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class
其区别在于:
WebMvcTest用于单元测试场景,需要指定待测试的Controller;他也会启动一个Spring容器,但只会加载其中部分MVC相关的内容,如Component、Service或者Repository等注解的Bean不会进行加载。
会加载的:Controller/ControllerAdvice/JsonComponent/Converter/Filter/WebMvcConfigurer/HandlerMethodArgumentResolver等;
SpringBootTest:用于集成测试场景,不需要指定待测试的Controller;它会启动一个完整的Spring容器,所有的Bean都会进行加载与初始化。
- Spring Boot常用测试场景及分析
- Spring Boot测试打桩-Mockito在Spring Boot中的常见测试场景
- etcd 集群搭建及常用场景分析
- etcd 集群搭建及常用场景分析
- spring boot 常用注释及用法
- Spring Boot Actuator 常用端点及描述
- 常用排序算法的性能分析及应用场景
- 常用排序算法的性能分析及应用场景
- spring boot 学习(三)API注解记录及测试
- spring boot 学习(三)API注解记录及测试
- Spring-Boot单元格测试
- spring boot 测试 单元测试
- Spring boot 测试
- Spring boot测试
- spring boot 集成测试
- Spring boot 测试
- spring-boot缓存测试
- 测试场景及测试素材
- NeedDownloadError: Need ffmpeg exe. 问题解决
- c# 常用的几个小方法
- [Leetcode] 529. Minesweeper 解题报告
- Linux vim操作
- React组件生命周期小结
- Spring Boot常用测试场景及分析
- vimrc配置文件(亲测,好用)
- 412. Fizz Buzz
- Java操作jdbc工具类
- mysql 数据安装后启用远程访问!
- JVM--浅谈垃圾收集机制
- # 元组综合练习 #
- SpringCloud—— eureka service
- 48. Rotate Image