# 7.9.5. 测试工具

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

**7.9.5.1. ConfigDataApplicationContextInitializer**

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

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

    // ...

}
```

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

**7.9.5.2. 测试属性值**

`TestPropertyValues`让您快速将属性添加到 `ConfigurableEnvironment`或`ConfigurableApplicationContext`. 您可以使用`key=value`字符串调用它，如下所示：

```java
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.out`和`System.err`输出的 JUnit `Extension`。要使用它，需要添加`@ExtendWith(OutputCaptureExtension.class)`和 injection`CapturedOutput`作为测试类构造函数或测试方法的参数，如下所示：

```java
@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 集成测试](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.spring-webflux-tests)以及[WebFlux 和 MVC 端到端测试](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.with-running-server)。与`TestRestTemplate`不同，它提供了流式的api. 建议使用 Apache HTTP 客户端（版本 4.3.2 或更高版本），但不是强制性的。如果您的类路径中有它，则通过适当地配置客户端来或的`TestRestTemplate`响应。如果您确实使用 Apache 的 HTTP 客户端，则会启用一些额外的测试友好功能：

* 不遵循重定向（因此您可以断言响应位置）。
* Cookie 被忽略（因此模板是无状态的）。

`TestRestTemplate`可以在集成测试中直接实例化，如下例所示：

```java
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_PORT`或`WebEnvironment.DEFINED_PORT`一起使用，您可以注入一个完全配置的`TestRestTemplate`并开始使用它。如有必要，可以通过`RestTemplateBuilder`bean 应用额外的定制。任何未指定主机和端口的 URL 都会自动连接到嵌入式服务器，如下例所示：

```java
@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));
        }

    }

}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.shiker.tech/spring-boot-can-kao-wen-dang/7.-he-xin-te-xing/7.9.-dan-yuan-ce-shi/7.9.5.-ce-shi-gong-ju.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
