在使用@SpringBootTest测试时可以指定一个端口,如@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 或 @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT),这样在测试时会启动Spring内嵌的Http Server。 这时就可以使用一个RestTemplate 或者 TestRestTemplate。 使用RANDOM_PORT和DEFINED_PORT的区别在于前着使用的是配置文件中的端口号(server.port,默认值为8080),后者使用的是一个随机端口号。在进行并行测试的时候可以使用随机端口号以避免端口冲突。 看下测试代码: Web Server测试 这里依然使用SpringRunner执行测试。同时使用@SpringBootTest注解的RANDOM_PORT 模式来得到一个内嵌的WebServer运行当前应用。 测试代码中使用RestTemplate来触发请求,这个过程和使用外部服务器很像。 测试中的assertion现在有了一点儿变化,因为要验证的返回值由MockHttpServletResponse变成了ResponseEntity。 TestRestTemplate 因为使用了@SpringBootTest注解,就可以使用@Autowired注解来获取TestRestTemplate的实例。这个TestRestTemplate实例的作用和常见的RestTemplate实例几乎没有任何区别,只是添加了一些额外的能力。实际上,可以将TestRestTemplate视为RestTemplate在测试环境的装饰类。 参与测试的角色关系如下图: 关于性能 也许我们会觉得第一个方案会更加有性能优势,因为它不需要加载Spring Context。事实上确实如此。但是即使加载了SpringContext,也不会造成特别恐怖的影响,因为在同一个Test Suite中,已经加载的Spring Context是可以重用的。 不过Spring Context重用也会导致一些问题,比如一些测试方法对公共的Bean做了修改就可能会影响到其他测试方法。此时可以使用@DirtiesContext注解来要求重新加载Context。 总结 到现在为止我们从轻到重共介绍了四种SpringBoot Controller测试方案。 虽然我们的目标一直都是对Controller层进行测试,但是从第一种测试方案(Standalone MockMVC)到现在,测试的角度还是有些变化的。一开始我们只是会加载测试的Controller类,却不会加载其周边的一些角色如Filter或Advice。到现在这个方案里我们启动了内嵌的WebServer,加载了整个SpringBoot Context。 目前这个方案是提到的四个测试方案里最重的一个,也是离单元测试的概念最远的一个。 下面说几个使用建议: 如果在单元测试中关注Controller的逻辑,优先选择第一种方案:Standalone MockMVC方案; 如果要测试Web层的其它角色(Filter或Advice)的行为,优先选择第四种测试方案执行集成测试; 避免将单元测试和集成测试混在一起,最好分开来写。 其他 Spring Controller测试 – 01 概述 Spring Controller测试 – 02 Standalone MockMVC Spring Controller测试 – 03 WebContext & MockMVC Spring Controller测试 – 04 SpringBootTest & MockMVC Spring Controller测试 – 05 SpringBootTest & WebServer 示例代码可在CSDN下载,地址:https://download.csdn.net/download/tianxiexingyun/11065824 参考文档:https://thepracticaldeveloper.com/2017/07/31/guide-spring-boot-controller-tests/
[阅读更多...]-
Spring Controller层测试 – 05 SpringBootTest & WebServer
-
Spring Controller层测试 – 04 SpringBootTest & MockMVC
这种测试方案会加载完整的SpringContext,但我们仍然不需要Web Server,需要继续通过MockMVC来模拟请求。 在测试的时候主要用到了@SpringBootTest注解。看下代码: @SpringBootTest和@AutoConfigureMockMvc 使用@SpringBootTest注解会加载整个Context。这样我们可以自动获得所有在Context中注入的Bean,以及从application.properties中加载的配置信息。 在@SpringBootTest中声明webEnvironment为WebEnvironment.MOCK(默认值就是WebEnvironment.MOCK)后,结合@AutoConfigureMockMvc注解,在测试的时候会得到一个模拟的Web/Servlet环境。 因为没有Web Server,所以就无法使用RestTemplate,也就只能继续使用MockMVC了。这次MockMVC的实例是由@AutoConfigureMockMvc注解来完成的。这归功于SpringBoot的自动化配置。 所有参与测试的对象的关系如下图: 总结 这种测试方案更倾向于集成测试。它的关注点主要在于SpringBoot不同类之间的交互。 在这个测试方案中,请求仍然是通过MockMVC模拟的。不过因为有一个完整的Context,请求处理过程中的所有逻辑都是真实的,请求返回结果也是真实的。因此测试效果和使用Web Server几乎是差不多的了。 如果还是要只测试Controller中的逻辑,也可以继续使用 @MockBean注解来mock一个IWorkerService实例来覆盖Context中已有的实例。即使使用了真正的WebServer,也可以继续使用MockBean。同样在测试中也需要继续mock数据。 概括来说,这种测试的位置稍显尴尬:如果要执行单元测试来测试WEB层的逻辑,建议优先第二种方案;如果要执行集成测试,启动一个真正的Web Server,使用RestTemplate进行测试会更彻底也更加方便。 Spring Controller测试 – 01 概述 Spring Controller测试 – 02 Standalone MockMVC Spring Controller测试 – 03 WebContext & MockMVC Spring Controller测试 – 04 SpringBootTest & MockMVC Spring Controller测试 – 05 SpringBootTest & WebServer 其他:示例代码可在CSDN下载,地址:https://download.csdn.net/download/tianxiexingyun/11065824
[阅读更多...]