初中做语文题的网站,做啥网站好,wordpress 首页 缩略图,英文seo推广集成测试可能很慢且不可靠#xff0c;因为它们依赖于系统中过多的组件。 在某种程度上#xff0c;这是不可避免的#xff1a;这里的集成测试是为了验证系统的每个部分如何与其他内部或外部组件一起玩。 但是#xff0c;我们可以通过仅分解所需的依赖关系而不是整个系统来改… 集成测试可能很慢且不可靠因为它们依赖于系统中过多的组件。 在某种程度上这是不可避免的这里的集成测试是为了验证系统的每个部分如何与其他内部或外部组件一起玩。 但是我们可以通过仅分解所需的依赖关系而不是整个系统来改进某些集成测试。 让我们想象一个依赖于数据库第三方REST API和消息队列的应用程序 现在假设我们希望集成测试验证仅包含对REST API的调用但不包含对数据库或消息队列的调用的行为。 举一个具体的例子假设我们要检查REST客户端是否正确配置为3秒钟后超时。 为此我们需要的是一个小型Controller 该Controller将在返回答案到REST客户端之前等待以模拟REST API。 等待时间将作为参数传递给查询字符串。 Profile(restTemplateTimeout)
RestController
RequestMapping(value /test)
public class DelayedWebServerController {RequestMapping(value /delayRestTemplate, method GET)public String answerWithDelay(RequestParam Long waitTimeMs) {if (waitTimeMs 0) {try {Thread.sleep(waitTimeMs);} catch (InterruptedException e) {throw new RuntimeException(e);}}return Delayed Result;}} Profile批注用于什么 如果我们将此控制器注入到我们的标准应用程序上下文中则有几个缺点 测试将会很慢我们只需要启动一个控制器而不是整个控制器 我们的控制器将由Spring拾取并注入其他所有集成测试中从而减慢每个集成测试的速度并可能踩到另一个测试的脚趾 更好的选择是启动一个最小的Spring Boot应用程序仅暴露我们的DelayedWebServerController 。 我们还将告诉Spring Boot仅扫描我们感兴趣的软件包并排除与持久性相关的自动配置因为我们不需要它来启动控制器。 这是在类似以下的Configuration类中完成的 Profile(restTemplateTimeout)
Configuration
EnableAutoConfiguration(exclude {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
ComponentScan(basePackages my.application.resttemplate.timeout)
public class DelayedWebServerConfiguration {//The class is empty and only used to support the annotations
} Spring上下文配置可能会引起混乱让我们一个接一个地查看批注 Profile 这告诉Spring只有在restTemplateTimeout配置文件处于活动状态时才应使用此配置。 在本文的进一步内容中我们将看到如何为特定的集成测试启用此配置文件。 正是这个注释防止配置被其他不相关的集成测试所采用。 请注意我们的DelayedWebServerController具有相同的注释。 Configuration 标准注释用于告诉Spring这是一个上下文配置类。 EnableAutoConfiguration 在这里我们禁用了某些不需要进行特定测试的Spring Boot“魔术” ComponentScan 通过仅扫描一个软件包而不是整个项目我们可以加快Spring Boot应用程序的启动速度。 Spring不会选择此包之外的任何带有Spring注释的类。 集成测试如下所示 RunWith(SpringJUnit4ClassRunner.class)
WebIntegrationTest(server.port:0)
SpringApplicationConfiguration(classes DelayedWebServerConfiguration.class)
ActiveProfiles(restTemplateTimeout)
public class RestTemplateShould {Rulepublic ExpectedException thrown none();Value(${local.server.port})private int port;Autowiredprivate RestTemplate restTemplate;Testpublic void throw_timeout_if_response_lasts_more_than_two_seconds() {thrown.expect(ResourceAccessException.class);thrown.expectCause(instanceOf(SocketTimeoutException.class));callEndpointWithDelay(3000);}Testpublic void do_not_throw_timeout_if_response_lasts_less_than_two_seconds() {callEndpointWithDelay(10);}private void callEndpointWithDelay(long delayMs) {restTemplate.getForObject(http://localhost: port /test/delayRestTemplate?waitTimeMs delayMs, String.class);}
} 当然所有这些类都存储在我们的测试源文件夹通常为src/test/java 中因为生产不需要它们。 让我们再看一下注解 RunWith 测试将使用Spring Junit运行程序该运行程序将负责为我们创建Spring上下文。 WebIntegrationTest 告诉Spring这是一个运行Web应用程序的集成测试否则默认情况下Spring不会在测试模式下运行HTTP服务器。 我们还将server.port的值设置为0以便Spring Boot选择一个随机端口供HTTP服务器监听。 这允许并行运行多个测试或者在后台运行该应用程序的另一个版本。 SpringApplicationConfiguration 我们告诉Spring在哪里可以找到我们之前创建的DelayedWebServerConfiguration类。 ActiveProfiles 启用restTemplateTimeout配置文件否则Controller和Configuration将被过滤掉。 现在我们有一个集成测试它以一组有限的依赖关系而不是整个应用程序运行。 如果我们想走得更远并在游戏中添加模拟游戏怎么办 当依赖项没有开发环境或者过于复杂而无法从开发人员的工作站调用时可能需要这样做。 在这种情况下我们可以将这些模拟添加到Configuration类中并将它们注入到测试的Spring上下文中。 这是一个Configuration示例在该示例中我们注入了一个由Mockito模拟的自定义CustomerService 而不是默认值 Profile(validationTests)
Configuration
EnableAutoConfiguration(exclude {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
ComponentScan(basePackages {my.application.controller,my.application.actions})
public class ValidationEndToEndConfiguration {Beanpublic CustomerService customerService() {return Mockito.mock(CustomerService.class);}
} 通过这种方法我们可以使集成测试更具弹性。 对于缓慢或不可靠的依赖关系让开发人员针对模拟版本运行集成测试会更加有效。 但是不要忘记最终您的应用程序将必须与实际系统集成而不是与模拟系统集成。 因此让持续集成服务器至少每天都在真实系统上运行测试是有意义的。 翻译自: https://www.javacodegeeks.com/2016/02/isolating-integration-tests-mocking-dependencies-spring-boot.html