7.9.5. 测试工具

测试应用程序时通常有用的一些测试实用程序类被打包为spring-boot.

7.9.5.1. ConfigDataApplicationContextInitializer

ConfigDataApplicationContextInitializer是一个ApplicationContextInitializer你可以应用到你的测试来加载 Spring Bootapplication.properties文件的工具。当您不需要 提供的全套功能时,您可以使用它,@SpringBootTest如下例所示:

@ContextConfiguration(classes = Config.class, initializers = ConfigDataApplicationContextInitializer.class)
class MyConfigFileTests {

    // ...

}

单独使用ConfigDataApplicationContextInitializer不支持@Value("${…}")注入。它唯一的工作是确保将application.properties文件加载到 Spring 的Environment. 为了获得@Value支持,您需要另外配置 PropertySourcesPlaceholderConfigurer@SpringBootTest,它会为您自动配置一个。

7.9.5.2. 测试属性值

TestPropertyValues让您快速将属性添加到 ConfigurableEnvironmentConfigurableApplicationContext. 您可以使用key=value字符串调用它,如下所示:

class MyEnvironmentTests {

    @Test
    void testPropertySources() {
        MockEnvironment environment = new MockEnvironment();
        TestPropertyValues.of("org=Spring", "name=Boot").applyTo(environment);
        assertThat(environment.getProperty("name")).isEqualTo("Boot");
    }

}

7.9.5.3. 输出捕获

OutputCapture是一个可用于捕获System.outSystem.err输出的 JUnit Extension。要使用它,需要添加@ExtendWith(OutputCaptureExtension.class)和 injectionCapturedOutput作为测试类构造函数或测试方法的参数,如下所示:

@ExtendWith(OutputCaptureExtension.class)
class MyOutputCaptureTests {

    @Test
    void testName(CapturedOutput output) {
        System.out.println("Hello World!");
        assertThat(output).contains("World");
    }

}

7.9.5.4. 测试RestTemplate

TestRestTemplate是 Spring 的一种方便替代方案,RestTemplate在集成测试中很有用。您可以获得一个普通模板或发送基本 HTTP 身份验证(带有用户名和密码)的模板。在任何一种情况下,模板都是容错的。这意味着它以一种测试友好的方式运行,不会在 4xx 和 5xx 错误上抛出异常。相反,可以通过返回ResponseEntity的及其状态码检测此类错误。

Spring Framework 5.0 提供了一个新功能WebTestClient,适用于WebFlux 集成测试以及WebFlux 和 MVC 端到端测试。与TestRestTemplate不同,它提供了流式的api. 建议使用 Apache HTTP 客户端(版本 4.3.2 或更高版本),但不是强制性的。如果您的类路径中有它,则通过适当地配置客户端来或的TestRestTemplate响应。如果您确实使用 Apache 的 HTTP 客户端,则会启用一些额外的测试友好功能:

  • 不遵循重定向(因此您可以断言响应位置)。

  • Cookie 被忽略(因此模板是无状态的)。

TestRestTemplate可以在集成测试中直接实例化,如下例所示:

class MyTests {

    private final TestRestTemplate template = new TestRestTemplate();

    @Test
    void testRequest() {
        ResponseEntity<String> headers = this.template.getForEntity("https://myhost.example.com/example", String.class);
        assertThat(headers.getHeaders().getLocation()).hasHost("other.example.com");
    }

}

或者,如果您将@SpringBootTest注解与WebEnvironment.RANDOM_PORTWebEnvironment.DEFINED_PORT一起使用,您可以注入一个完全配置的TestRestTemplate并开始使用它。如有必要,可以通过RestTemplateBuilderbean 应用额外的定制。任何未指定主机和端口的 URL 都会自动连接到嵌入式服务器,如下例所示:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MySpringBootTests {

    @Autowired
    private TestRestTemplate template;

    @Test
    void testRequest() {
        HttpHeaders headers = this.template.getForEntity("/example", String.class).getHeaders();
        assertThat(headers.getLocation()).hasHost("other.example.com");
    }

    @TestConfiguration(proxyBeanMethods = false)
    static class RestTemplateBuilderConfiguration {

        @Bean
        RestTemplateBuilder restTemplateBuilder() {
            return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1))
                    .setReadTimeout(Duration.ofSeconds(1));
        }

    }

}

最后更新于