# 7.9.3. 测试 Spring Boot 应用程序

Spring Boot 应用程序是 Spring `ApplicationContext`，因此除了您通常使用普通 Spring 上下文执行的操作之外，无需进行任何特别的测试即可对其进行测试。

> 默认情况下，Spring Boot 的外部属性、日志记录和其他功能仅在您用于`SpringApplication`创建上下文时安装在上下文中。

Spring Boot 提供了`@SpringBootTest`注解，当您需要 Spring Boot 特性时，可以将其用作标准`spring-test` `@ContextConfiguration`注解的替代方案。该注解的工作原理是通过 SpringApplication 创建测试中使用的 ApplicationContext. 除了`@SpringBootTest`许多其他注解之外，还提供了用于[测试应用程序更具体的切面](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.autoconfigured-tests)。

> 如果您使用的是 JUnit 4，请不要忘记也添加`@RunWith(SpringRunner.class)`到您的测试中，否则注解将被忽略。如果您使用的是 JUnit 5，不需要添加等效的 `@ExtendWith(SpringExtension.class)`作为`@SpringBootTest`，并且其他`@…Test`注解已经用它注解了。

默认情况下，`@SpringBootTest`不会启动服务器。您可以使用`@SpringBootTest` 的`webEnvironment`属性来进一步优化测试的运行方式：

* `MOCK`（默认）：加载web `ApplicationContext`并提供模拟网络环境。使用此注解时不启动嵌入式服务器。如果您的类路径上没有可用的 Web 环境，则此模式会透明地回退到创建常规的 non-web `ApplicationContext`。它可以与您的 Web 应用程序结合使用[`@AutoConfigureMockMvc`或`@AutoConfigureWebTestClient`](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.with-mock-environment)用于基于模拟的测试。
* `RANDOM_PORT`: 加载`WebServerApplicationContext`并提供一个真实的网络环境。嵌入式服务器会启动并侦听随机端口。
* `DEFINED_PORT`: 加载`WebServerApplicationContext`并提供一个真实的网络环境。嵌入式服务器会启动并侦听定义的端口（来自您的`application.properties`）或默认的`8080`端口.
* `NONE`：通过使用`SpringApplication`加载一个`ApplicationContext`但不提供*任何*Web 环境（模拟或其他）。

> 如果您的测试是`@Transactional`，默认情况下，它会在每个测试方法结束时回滚事务。然而，由于使用`RANDOM_PORT`或`DEFINED_PORT`隐含地提供了一个真正的 servlet 环境，HTTP 客户端和服务器在不同的线程中运行，因此在不同的事务中运行。在这种情况下，服务器上启动的任何事务都不会回滚。
>
> 如果您的应用程序为管理服务器使用不同的端口， 使用`webEnvironment = WebEnvironment.RANDOM_PORT`的 `@SpringBootTest`还将在单独的随机端口上启动管理服务器。

7.&#x39;**.3.1. 检测 Web 应用程序类型**

如果 Spring MVC 可用，则配置常规的基于 MVC 的应用程序上下文。如果您只有 Spring WebFlux，我们将检测到它并配置一个基于 WebFlux 的应用程序上下文。

如果两者都存在，则 Spring MVC 优先。如果要在这种情况下测试响应式 Web 应用程序，则必须设置`spring.main.web-application-type`属性：

```java
@SpringBootTest(properties = "spring.main.web-application-type=reactive")
class MyWebFluxTests {

    // ...

}
```

7.&#x39;**.3.2. 检测测试配置**

如果您熟悉 Spring Test Framework，您可能习惯于使用`@ContextConfiguration(classes=…)`以指定要加载的 Spring `@Configuration`。或者，您可能经常在测试中使用嵌套`@Configuration`类。

在测试 Spring Boot 应用程序时，通常不需要这样做。只要您没有明确定义，Spring Boot 的`@*Test`注解就会自动搜索您的主要配置。

搜索算法从包含测试的包开始，直到找到一个用`@SpringBootApplication`或`@SpringBootConfiguration`注解的类。只要您以合理的方式[构建代码](https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.structuring-your-code)，通常会找到您的主要配置。

> 如果您使用[测试注解来测试应用程序的更具体部分](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.autoconfigured-tests)，则应避免在[主方法的应用程序类](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.user-configuration-and-slicing)上添加特定于特定区域的配置设置。`@SpringBootApplication`的底层组件扫描配置定义了用于确保切面按预期工作的排除过滤器。如果您在 `@SpringBootApplication`注解的类上使用显式`@ComponentScan`指令，请注意这些过滤器将被禁用。如果您使用切面，则应重新定义它们。

如果要自定义主要配置，可以使用嵌套`@TestConfiguration`类。与将使用嵌套`@Configuration`类代替应用程序的主要配置不同，嵌套`@TestConfiguration`类是在应用程序的主要配置之外使用的。

> Spring 的测试框架在测试之间缓存应用程序上下文。因此，只要您的测试共享相同的配置（无论它是如何被发现的），加载上下文的潜在耗时过程只会发生一次。

7.&#x39;**.3.3. 排除测试配置**

如果您的应用程序使用组件扫描（例如，如果您使用`@SpringBootApplication`或`@ComponentScan`），您可能会发现仅为特定测试创建的顶级配置类意外地在各处被拾取。

正如我们[之前看到的](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.detecting-configuration)，`@TestConfiguration`可以在测试的内部类上使用来自定义主要配置。当放置在顶级类上时，`@TestConfiguration`表示不应通过扫描获取`src/test/java`中的类。然后，您可以在需要的地方显式导入该类，如以下示例所示：

```java
@SpringBootTest
@Import(MyTestsConfiguration.class)
class MyTests {

    @Test
    void exampleTest() {
        // ...
    }

}
```

如果您直接使用`@ComponentScan`（即不通过`@SpringBootApplication`），则需要向`TypeExcludeFilter`注册。有关详细信息，请参阅[Javadoc](https://docs.spring.io/spring-boot/docs/2.7.3/api/org/springframework/boot/context/TypeExcludeFilter.html)。

7.&#x39;**.3.4. 使用应用程序参数**

如果您的应用程序需要[arguments](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.spring-application.application-arguments)，您可以使用`@SpringBootTest`的`args`属性注入它们。

```java
@SpringBootTest(args = "--app.test=one")
class MyApplicationArgumentTests {

    @Test
    void applicationArgumentsPopulated(@Autowired ApplicationArguments args) {
        assertThat(args.getOptionNames()).containsOnly("app.test");
        assertThat(args.getOptionValues("app.test")).containsOnly("one");
    }

}
```

7.&#x39;**.3.5. 使用模拟环境进行测试**

默认情况下，`@SpringBootTest`不会启动服务器，而是设置一个模拟环境来测试 Web 端点。

使用 Spring MVC，我们可以使用[`MockMvc`](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#spring-mvc-test-framework)或者`WebTestClient`查询我们的 Web 端点，如下例所示：

```java
@SpringBootTest
@AutoConfigureMockMvc
class MyMockMvcTests {

    @Test
    void testWithMockMvc(@Autowired MockMvc mvc) throws Exception {
        mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World"));
    }

    // If Spring WebFlux is on the classpath, you can drive MVC tests with a WebTestClient
    @Test
    void testWithWebTestClient(@Autowired WebTestClient webClient) {
        webClient
                .get().uri("/")
                .exchange()
                .expectStatus().isOk()
                .expectBody(String.class).isEqualTo("Hello World");
    }

}
```

> 如果您只想专注于 web 层而不是开始一个完整的`ApplicationContext`，请考虑[改用`@WebMvcTest`](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.spring-mvc-tests).

使用 Spring WebFlux 端点，您可以如下示例所示使用[`WebTestClient`](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#webtestclient-tests)：

```java
@SpringBootTest
@AutoConfigureWebTestClient
class MyMockWebTestClientTests {

    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient
            .get().uri("/")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Hello World");
    }

}
```

在模拟环境中进行测试通常比使用完整的 servlet 容器运行更快。但是，由于 mocking 发生在 Spring MVC 层，依赖于较低级别 servlet 容器行为的代码不能直接使用 MockMvc 进行测试。例如，Spring Boot 的错误处理是基于 servlet 容器提供的“错误页面”支持。这意味着，虽然您可以按预期测试您的 MVC 层抛出和处理异常，但您不能直接测试是否呈现了特定的[自定义错误页面。](https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.servlet.spring-mvc.error-handling.error-pages)如果您需要测试这些较低级别的问题，您可以启动一个完全运行的服务器，如下一节所述。

7.&#x39;**.3.6. 使用正在运行的服务器进行测试**

如果您需要启动一个完整运行的服务器，我们建议您使用随机端口。如果您使用`@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)`，则每次运行测试时都会随机选择一个可用端口。

`@LocalServerPort`注解可用于将实际使用的[端口注入](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.webserver.discover-port)到您的测试中。为方便起见，需要对启动的服务器进行 REST 调用的测试可以通过额外添加`@Autowire`装配的[`WebTestClient`](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#webtestclient-tests)，它解析到正在运行的服务器的相关链接，并带有用于验证响应的专用 API，如下例所示：

```java
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortWebTestClientTests {

    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient
            .get().uri("/")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Hello World");
    }

}
```

> `WebTestClient`可用于实时服务器和[模拟环境](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.with-mock-environment)。

此设置需要在类路径上有`spring-webflux`。如果你不能或不会添加 webflux，Spring Boot 还提供了一个`TestRestTemplate`工具：

```java
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortTestRestTemplateTests {

    @Test
    void exampleTest(@Autowired TestRestTemplate restTemplate) {
        String body = restTemplate.getForObject("/", String.class);
        assertThat(body).isEqualTo("Hello World");
    }

}
```

7.&#x39;**.3.7. 自定义 WebTestClient**

要自定义`WebTestClient`bean，请配置一个`WebTestClientBuilderCustomizer`bean。任何此类 bean 都使用`WebTestClient.Builder`创建`WebTestClient`.

7.&#x39;**.3.8. 使用 JMX**

由于测试上下文框架缓存了上下文，JMX 默认是禁用的，以防止相同的组件在同一个域上注册。如果此类测试需要访问`MBeanServer`，请考虑将其标记为dirty：

```java
@ExtendWith(SpringExtension.class)
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
class MyJmxTests {

    @Autowired
    private MBeanServer mBeanServer;

    @Test
    void exampleTest() {
        assertThat(this.mBeanServer.getDomains()).contains("java.lang");
        // ...
    }

}
```

7.&#x39;**.3.9. 使用指标**

无论您的类路径如何，使用 `@SpringBootTest` 时，仪表注册表（内存中支持的除外）都不会自动配置。

如果您需要在集成测试中将指标导出到不同的后端，请使用`@AutoConfigureMetrics`.

7.&#x39;**.3.10. 模拟和窥探 Bean**

运行测试时，有时需要在应用程序上下文中模拟某些组件。例如，您可能有一些在开发期间不可用的远程服务的外观。当您想要模拟在真实环境中可能难以触发的故障时，模拟也很有用。

Spring Boot 包含一个`@MockBean`注解，可用于为您的`ApplicationContext`. 您可以使用注解添加新 bean 或替换单个现有 bean 定义。注解可以直接用于测试类、测试中的字段或`@Configuration`类和字段。在字段上使用时，创建的模拟实例也会被注入。在每个测试方法之后，模拟 bean 都会自动重置。

> 如果您的测试使用 Spring Boot 的测试注解之一（例如`@SpringBootTest`），则会自动启用此功能。要以不同的排列方式使用此功能，必须显式添加侦听器，如以下示例所示：
>
> ```
> @ContextConfiguration(classes = MyConfig.class)
> @TestExecutionListeners({ MockitoTestExecutionListener.class, ResetMocksTestExecutionListener.class })
> class MyTests {
>
>  // ...
>
> }
> ```

以下示例将现有`RemoteService`bean 替换为模拟实现：

```java
@SpringBootTest
class MyTests {

    @Autowired
    private Reverser reverser;

    @MockBean
    private RemoteService remoteService;

    @Test
    void exampleTest() {
        given(this.remoteService.getValue()).willReturn("spring");
        String reverse = this.reverser.getReverseValue(); // Calls injected RemoteService
        assertThat(reverse).isEqualTo("gnirps");
    }

}
```

> `@MockBean`不能用于模拟在应用程序上下文刷新期间执行的 bean 的行为。到执行测试时，应用程序上下文刷新已完成，配置模拟行为为时已晚。我们建议在这种情况下使用`@Bean`方法来创建和配置模拟。

此外，您可以使用 `@SpyBean` 将任何现有的 `bean` 与 `Mockito spy` 包装在一起。有关完整详细信息，请参阅 Javadoc。

> CGLib 代理，例如为作用域 bean 创建的代理，将代理方法声明为`final`. 这会阻止 Mockito 正常运行，因为它无法在其默认配置中模拟或监视`final`方法。如果您想模拟或监视这样的 bean，请将 Mockito 配置为通过`org.mockito:mockito-inline`添加到应用程序的测试依赖项来使用其内联模拟生成器。这允许 Mockito 模拟和监视`final`方法。 虽然 Spring 的测试框架在测试之间缓存应用程序上下文，并为共享相同配置的测试重用上下文，但使用`@MockBean`或`@SpyBean`影响缓存键，这很可能会增加上下文的数量。 如果您使用`@SpyBean`通过名称引用参数的`@Cacheable`方法来监视 bean ，则您的应用程序必须使用`-parameters`. 这确保了一旦 bean 被监视，参数名称对缓存基础设施可用。 当您使用`@SpyBean`用于监视由 Spring 代理的 bean 时，您可能需要在某些情况下删除 Spring 的代理，例如在使用`given`或`when`设置期望值时。使用`AopTestUtils.getTargetObject(yourProxiedSpy)`也需要这样做。

7.&#x39;**.3.11. 自动配置的测试**

Spring Boot 的自动配置系统适用于应用程序，但有时对于测试来说有点太多了。它通常有助于仅加载测试应用程序“切面”所需的配置部分。例如，您可能想要测试 Spring MVC 控制器是否正确映射 URL，并且您不想在这些测试中涉及数据库调用，或者您可能想要测试 JPA 实体，而当这些测试运行。

`spring-boot-test-autoconfigure`模块包含许多注解，可用于自动配置此类“切面”。它们中的每一个都以类似的方式工作，它们中的每一个都以类似的方式工作，提供一个加载`ApplicationContext`的 `@…Test` 注解和一个或多个可用于自定义自动配置设置的`@AutoConfigure…`注解。

> 每个切面将组件扫描限制到适当的组件并加载一组非常有限的自动配置类。如果您需要排除其中一个，大多数`@…Test`注解都提供了一个`excludeAutoConfiguration`属性。或者，您也可以使用`@ImportAutoConfiguration#exclude`.
>
> 不支持通过在一个测试中使用多个`@…Test`注解来包含多个“切面” 。如果您需要多个“切面”，请选择其中一个`@…Test`注解并手动包含其他“切面”的`@AutoConfigure…`注解。
>
> 如果您对“切面”您的应用程序不感兴趣，但您想要一些自动配置的测试 bean，您也可以将`@AutoConfigure…`注解与标准`@SpringBootTest`注解一起使用。

7.&#x39;**.3.12. 自动配置的 JSON 测试**

要测试对象 JSON 序列化和反序列化是否按预期工作，您可以使用`@JsonTest`注解。 `@JsonTest`自动配置可用的支持 JSON 映射器，它可以是以下库之一：

* Jackson`ObjectMapper`，任何`@JsonComponent`bean和任何Jackson `Module`的
* `Gson`
* `Jsonb`

> 可以[在附录](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)中找到启用`@JsonTest`的自动配置列表。

如果需要配置自动配置的元素，可以使用`@AutoConfigureJsonTesters`注解。

Spring Boot 包括基于 AssertJ 的帮助程序，它们与 JSONAssert 和 JsonPath 库一起检查 JSON 是否按预期显示。`JacksonTester`、`GsonTester`和`BasicJsonTester`类可分别用于 Jackson、Gson、Jsonb 和 Strings 。使用 `@JsonTest` 时，测试类上的任何辅助字段都可以是 `@Autowired`。. 以下示例显示了 Jackson 的测试类：

```java
@JsonTest
class MyJsonTests {

    @Autowired
    private JacksonTester<VehicleDetails> json;

    @Test
    void serialize() throws Exception {
        VehicleDetails details = new VehicleDetails("Honda", "Civic");
        // Assert against a `.json` file in the same package as the test
        assertThat(this.json.write(details)).isEqualToJson("expected.json");
        // Or use JSON path based assertions
        assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
        assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make").isEqualTo("Honda");
    }

    @Test
    void deserialize() throws Exception {
        String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
        assertThat(this.json.parse(content)).isEqualTo(new VehicleDetails("Ford", "Focus"));
        assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
    }

}
```

JSON 辅助类也可以直接用于标准单元测试。为此，如果您不使用 `@JsonTest`，请在 `@Before` 方法中调用帮助器的 `initFields` 方法。

如果您使用 Spring Boot 的基于 AssertJ 的帮助器对给定 JSON 路径中的数字值进行断言，则可能无法使用，`isEqualTo`具体取决于类型。相反，您可以使用 AssertJ`satisfies`断言该值与给定条件是否匹配。例如，以下示例断言实际数字是否接近浮点值`0.15`，偏移量`0.01`。

```java
@Test
void someTest() throws Exception {
    SomeObject value = new SomeObject(0.152f);
    assertThat(this.json.write(value)).extractingJsonPathNumberValue("@.test.numberValue")
            .satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));
}
```

**8.3.13. 自动配置的 Spring MVC 测试**

要测试 Spring MVC 控制器是否按预期工作，请使用`@WebMvcTest`注解。 `@WebMvcTest`自动配置 Spring MVC 基础结构并将扫描的 bean 限制为`@Controller`, `@ControllerAdvice`, `@JsonComponent`, `Converter`, `GenericConverter`, `Filter`, `HandlerInterceptor`, `WebMvcConfigurer`,`WebMvcRegistrations`和`HandlerMethodArgumentResolver`. 使用注解`@WebMvcTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) 启用`@WebMvcTest`的自动配置设置列表。

如果您需要注册额外的组件，例如 Jackson `Module`，您可以通过在测试中使用`@Import`来导入额外的配置类。 通常，`@WebMvcTest`仅限于单个控制器，并与`@MockBean`结合使用，为所需的协作者提供模拟实现。

`@WebMvcTest`也可以自动配置`MockMvc`。Mock MVC 提供了一种强大的方法来快速测试 MVC 控制器，而无需启动完整的 HTTP 服务器。

您还可以在非`@WebMvcTest`中通过使用`@AutoConfigureMockMvc`注解来自动配置`MockMvc`（例如`@SpringBootTest`） 。以下示例使用`MockMvc`：

```java
@WebMvcTest(UserVehicleController.class)
class MyControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
            .willReturn(new VehicleDetails("Honda", "Civic"));
        this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
            .andExpect(status().isOk())
            .andExpect(content().string("Honda Civic"));
    }

}
```

如果您需要配置自动配置的元素（例如，当使用 servlet 过滤器时），您可以在`@AutoConfigureMockMvc`注解中使用属性。 如果您使用 HtmlUnit 和 Selenium，自动配置还提供 HtmlUnit `WebClient`bean 和/或 Selenium `WebDriver`bean。以下示例使用 HtmlUnit：

```java
@WebMvcTest(UserVehicleController.class)
class MyHtmlUnitTests {

    @Autowired
    private WebClient webClient;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot")).willReturn(new VehicleDetails("Honda", "Civic"));
        HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
        assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
    }

}
```

> 默认情况下，Spring Boot 将`WebDriver`bean 放在一个特殊的“域”中，以确保驱动程序在每次测试后退出并注入新实例。如果您不想要这种行为，您可以添加`@Scope("singleton")`到您的`WebDriver` `@Bean`定义中。 Spring Boot 创建的`webDriver`域将替换任何用户定义的同名域。如果您定义自己的`webDriver`域，您可能会发现在使用`@WebMvcTest`它会停止工作. 如果类路径上有 Spring Security，`@WebMvcTest`也会扫描`WebSecurityConfigurer`bean。您可以使用 Spring Security 的测试支持，而不是完全禁用此类测试的安全性。有关如何使用 Spring Security`MockMvc`支持的更多详细信息，请参见\*[howto.html](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.testing.with-spring-security)\* how-to 部分。

有时编写 Spring MVC 测试是不够的；Spring Boot 可以帮助您[使用实际的服务器运行完整的端到端测试](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.with-running-server)。

7.&#x39;**.3.14. 自动配置的 Spring WebFlux 测试**

要测试[Spring WebFlux](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/web-reactive.html)控制器是否按预期工作，您可以使用`@WebFluxTest`注解。 `@WebFluxTest`自动配置 Spring WebFlux 基础结构并将扫描的 bean 限制为`@Controller`、`@ControllerAdvice`、`@JsonComponent`、`Converter`、`GenericConverter`、`WebFilter`和`WebFluxConfigurer`. 使用注解`@WebFluxTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。

可以[在附录](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)中找到 启用`@WebFluxTest`的自动配置列表。 如果您需要注册额外的组件，例如 Jackson `Module`，您可以在您的测试中 使用`@Import`导入额外的配置类。 通常，`@WebFluxTest`仅限于单个控制器并与`@MockBean`注解结合使用，为所需的协作者提供模拟实现。

`@WebFluxTest`还自动配置了 [`WebTestClient`](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#webtestclient)，它提供了一种强大的方法来快速测试 WebFlux 控制器，而无需启动完整的 HTTP 服务器。

您还可以在非`@WebFluxTest`中通过使用`@AutoConfigureWebTestClient`注解来自动配置`WebTestClient`（例如`@SpringBootTest`） 。以下示例使用`WebTestClient`和`@WebFluxTest`：

```java
@WebFluxTest(UserVehicleController.class)
class MyControllerTests {

    @Autowired
    private WebTestClient webClient;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    void testExample() {
        given(this.userVehicleService.getVehicleDetails("sboot"))
            .willReturn(new VehicleDetails("Honda", "Civic"));
        this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN).exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Honda Civic");
    }

}
```

此设置仅受 WebFlux 应用程序支持，因为在模拟应用程序中使用`WebTestClient`目前仅适用于 WebFlux。

`@WebFluxTest`无法检测通过功能性 Web 框架注册的路由。要在上下文中测试`RouterFunction`bean，请考虑通过使用`@Import`或使用`@SpringBootTest`导入您自己的`RouterFunction`。 `@WebFluxTest`无法检测作为`@Bean`类型注册的自定义安全配置`SecurityWebFilterChain`。要将其包含在您的测试中，您需要通过使用`@Import`或使用`@SpringBootTest`导入注册 bean 的配置。 有时编写 Spring WebFlux 测试是不够的；Spring Boot 可以帮助您[使用实际的服务器运行完整的端到端测试](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.with-running-server)。

7.&#x39;**.3.15。自动配置的 Spring GraphQL 测试**

Spring GraphQL 提供了专门的测试支持模块；您需要将其添加到您的项目中： *Maven*

```xml
<dependencies>
    <dependency>
        <groupId>org.springframework.graphql</groupId>
        <artifactId>spring-graphql-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- Unless already present in the compile scope -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
```

*Gradle*

```gradle
dependencies {
    testImplementation("org.springframework.graphql:spring-graphql-test")
    // Unless already present in the implementation configuration
    testImplementation("org.springframework.boot:spring-boot-starter-webflux")
}
```

这个测试模块附带了[GraphQlTester](https://docs.spring.io/spring-graphql/docs/1.0.1/reference/html/#testing-graphqltester)。测试仪在测试中大量使用，所以一定要熟悉使用它。有了`GraphQlTester`变体，Spring Boot 将根据测试类型自动配置它们：

* `ExecutionGraphQlServiceTester`在服务器端执行测试，没有客户端也没有实际传输
* 使用`HttpGraphQlTester`连接到服务器的客户端执行测试，有或没有服务器都可以

Spring Boot 可帮助您使用`@GraphQlTest`注解测试[Spring GraphQL 控制器](https://docs.spring.io/spring-graphql/docs/1.0.1/reference/html/#controllers)。 `@GraphQlTest`自动配置 Spring GraphQL 基础设施，不涉及任何传输或服务器。这会将扫描的bean 限制为`@Controller`、`RuntimeWiringConfigurer`、`JsonComponent`、`Converter`、`GenericConverter`、`DataFetcherExceptionResolver`、`Instrumentation`和`GraphQlSourceBuilderCustomizer`。使用注解`@GraphQlTest`时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。

可以[在附录](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)中找到`@GraphQlTest` 启用的自动配置列表。

如果您需要注册额外的组件，例如 Jackson `Module`，您可以在您的测试中使用`@Import`导入额外的配置类。 通常，`@GraphQlTest`仅限于一组控制器并与`@MockBean`注解结合使用，为所需的协作者提供模拟实现。

```java
@GraphQlTest(GreetingController.class)
class GreetingControllerTests {

    @Autowired
    private GraphQlTester graphQlTester;

    @Test
    void shouldGreetWithSpecificName() {
        this.graphQlTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class)
                .isEqualTo("Hello, Alice!");
    }

    @Test
    void shouldGreetWithDefaultName() {
        this.graphQlTester.document("{ greeting } ").execute().path("greeting").entity(String.class)
                .isEqualTo("Hello, Spring!");
    }

}
```

`@SpringBootTest`测试是完整的集成测试，涉及整个应用程序。当使用随机或定义的端口时，会配置一个实时服务器并自动提供一个`HttpGraphQlTester` bean，以便您可以使用它来测试您的服务器。配置 MOCK 环境后，您还可以通过使用以下命令`@AutoConfigureHttpGraphQlTester` 注解测试类来请求`HttpGraphQlTester` bean ：

```java
@AutoConfigureHttpGraphQlTester
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class GraphQlIntegrationTests {

    @Test
    void shouldGreetWithSpecificName(@Autowired HttpGraphQlTester graphQlTester) {
        HttpGraphQlTester authenticatedTester = graphQlTester.mutate()
                .webTestClient(
                        (client) -> client.defaultHeaders((headers) -> headers.setBasicAuth("admin", "ilovespring")))
                .build();
        authenticatedTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class)
                .isEqualTo("Hello, Alice!");
    }

}
```

**8.3.16. 自动配置的数据 Cassandra 测试**

您可以使用`@DataCassandraTest`来测试 Cassandra 应用程序。默认情况下，它配置一个`CassandraTemplate`，来扫描`@Table`类，并配置 Spring Data Cassandra 存储库。使用注解`@DataCassandraTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。（有关在 Spring Boot 中使用 Cassandra 的更多信息，请参阅“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.cassandra) ”。）

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)`@DataCassandraTest`启用的自动配置设置列表。

以下示例显示了在 Spring Boot 中使用 Cassandra 测试的典型设置：

```java
@DataCassandraTest
class MyDataCassandraTests {

    @Autowired
    private SomeRepository repository;

}
```

7.&#x39;**.3.17. 自动配置的 Data Couchbase 测试**

您可以使用`@DataCouchbaseTest`来测试 Couchbase 应用程序。默认情况下，它配置一个`CouchbaseTemplate`或者 `ReactiveCouchbaseTemplate`，扫描`@Document`类，并配置 Spring Data Couchbase 存储库。使用注解`@DataCouchbaseTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。（有关在 Spring Boot 中使用 Couchbase 的更多信息，请参阅本章前面的“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.couchbase) ”。）

`@DataCouchbaseTest`可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) 启用的自动配置设置列表。 以下示例显示了在 Spring Boot 中使用 Couchbase 测试的典型设置：

```java
@DataCouchbaseTest
class MyDataCouchbaseTests {

    @Autowired
    private SomeRepository repository;

    // ...

}
```

7.&#x39;**.3.18. 自动配置的数据 Elasticsearch 测试**

您可以使用`@DataElasticsearchTest`来测试 Elasticsearch 应用程序。默认情况下，它配置一个`ElasticsearchRestTemplate`，扫描`@Document`类，并配置 Spring Data Elasticsearch 存储库。使用注解`@DataElasticsearchTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。（有关在 Spring Boot 中使用 Elasticsearch 的更多信息，请参阅本章前面的“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.elasticsearch) ”。）

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) `@DataElasticsearchTest`启用的自动配置设置列表。 以下示例显示了在 Spring Boot 中使用 Elasticsearch 测试的典型设置：

```java
@DataElasticsearchTest
class MyDataElasticsearchTests {

    @Autowired
    private SomeRepository repository;

    // ...

}
```

7.&#x39;**.3.19. 自动配置的数据 JPA 测试**

您可以使用`@DataJpaTest`注解来测试 JPA 应用程序。默认情况下，它会扫描`@Entity`类并配置 Spring Data JPA 存储库。如果类路径上有一个嵌入式数据库，它也会配置一个。默认情况下，通过将`spring.jpa.show-sql`属性设置为`true`来记录 SQL 查询。这可以使用`showSql()`注解的属性来禁用。

使用注解`@DataJpaTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties` bean。

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) `@DataJpaTest`启用的自动配置设置列表。 默认情况下，数据 JPA 测试是事务性的，并在每个测试结束时回滚。有关更多详细信息，请参阅 Spring Framework 参考文档中的[相关部分](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#testcontext-tx-enabling-transactions)。如果这不是您想要的，您可以为测试或整个班级禁用事务管理，如下所示：

```java
@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyNonTransactionalTests {

    // ...

}
```

数据 JPA 测试也可以注入一个bean，它提供了一个专门为测试设计[`TestEntityManager`](https://github.com/spring-projects/spring-boot/tree/v2.7.3/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestEntityManager.java)的标准 JPA`EntityManager` 的替代方案。 `TestEntityManager`也可以通过添加`@AutoConfigureTestEntityManager`自动配置到任何基于 Spring 的测试类。这样做时，请确保您的测试在事务中运行，例如通过添加`@Transactional`到您的测试类或方法。 如果您需要，也可以使用`JdbcTemplate`。以下示例显示了`@DataJpaTest`正在使用的注解：

```java
@DataJpaTest
class MyRepositoryTests {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private UserRepository repository;

    @Test
    void testExample() {
        this.entityManager.persist(new User("sboot", "1234"));
        User user = this.repository.findByUsername("sboot");
        assertThat(user.getUsername()).isEqualTo("sboot");
        assertThat(user.getEmployeeNumber()).isEqualTo("1234");
    }

}
```

内存嵌入式数据库通常适用于测试，因为它们速度快且不需要任何安装。但是，如果您更喜欢针对真实数据库运行测试，则可以使用`@AutoConfigureTestDatabase`注解，如以下示例所示：

```java
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
class MyRepositoryTests {

    // ...

}
```

7.&#x39;**.3.20. 自动配置的 JDBC 测试**

`@JdbcTest`类似于`@DataJpaTest`但适用于只需要一个`DataSource`并且不使用 Spring Data JDBC 的测试。默认情况下，它配置一个内存嵌入式数据库和一个`JdbcTemplate`. 使用注解 `@JdbcTest`时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties` bean。

可以[在附录](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)中找到`@JdbcTest` 启用的自动配置列表。 默认情况下，JDBC 测试是事务性的，并在每次测试结束时回滚。有关更多详细信息，请参阅 Spring Framework 参考文档中的[相关部分](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#testcontext-tx-enabling-transactions)。如果这不是您想要的，您可以为测试或整个班级禁用事务管理，如下所示：

```java
@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyTransactionalTests {

}
```

如果您希望您的测试针对真实数据库运行，您可以使用与`DataJpaTest`相同的方式使用注解`@AutoConfigureTestDatabase` 。（请参阅“[自动配置的数据 JPA 测试](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.autoconfigured-spring-data-jpa)”。）

7.&#x39;**.3.21. 自动配置的数据 JDBC 测试**

`@DataJdbcTest`类似于`@JdbcTest`但适用于使用 Spring Data JDBC 存储库的测试。默认情况下，它配置内存中的嵌入式数据库、`JdbcTemplate`和 Spring Data JDBC 存储库。使用`@DataJdbcTest`注解时只`AbstractJdbcConfiguration`扫描子类，不扫描常规`@Component`和`@ConfigurationProperties`bean。 `@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。

可以[在附录](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)中找到`@DataJdbcTest`启用的自动配置列表。 默认情况下，Data JDBC 测试是事务性的，并在每次测试结束时回滚。有关更多详细信息，请参阅 Spring Framework 参考文档中的[相关部分](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#testcontext-tx-enabling-transactions)。如果这不是您想要的，您可以禁用测试或整个测试类的事务管理，如[JDBC 示例中所示](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.autoconfigured-jdbc)。

如果您希望您的测试针对真实数据库运行，您可以使用与`DataJpaTest`相同的方式使用注解`@AutoConfigureTestDatabase` 。（请参阅“[自动配置的数据 JPA 测试](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.autoconfigured-spring-data-jpa)”。）

7.&#x39;**.3.22。自动配置的 jOOQ 测试**

您可以使用与`@JdbcTest`相似的方式使用`@JooqTest`进行jOOQ 相关测试。由于 jOOQ 严重依赖与数据库模式相对应的基于 Java 的模式，因此会使用现有`DataSource`。如果您想用内存数据库替换它，您可以使用`@AutoConfigureTestDatabase`覆盖这些设置。（有关在 Spring Boot 中使用 jOOQ 的更多信息，请参阅“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.sql.jooq) ”。）使用注解`@JooqTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。

可以[在附录](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)中找到`@JooqTest` 启用的自动配置列表。 `@JooqTest`配置一个`DSLContext`. 以下示例显示了`@JooqTest`正在使用的注解：

```java
@JooqTest
class MyJooqTests {

    @Autowired
    private DSLContext dslContext;

    // ...

}
```

JOOQ 测试是事务性的，默认情况下会在每个测试结束时回滚。如果这不是您想要的，您可以禁用测试或整个测试类的事务管理，如[JDBC 示例中所示](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.autoconfigured-jdbc)。

7.&#x39;**.3.23. 自动配置数据 MongoDB 测试**

您可以使用`@DataMongoTest`来测试 MongoDB 应用程序。默认情况下，它配置一个内存中的嵌入式 MongoDB（如果可用），配置一个`MongoTemplate`，扫描`@Document`类，并配置 Spring Data MongoDB 存储库。使用注解`@DataMongoTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。（有关在 Spring Boot 中使用 MongoDB 的更多信息，请参阅“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.mongodb) ”。）

`@DataMongoTest`可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) 启用的自动配置设置列表。 下面的类显示了`@DataMongoTest`正在使用的注解：

```java
@DataMongoTest
class MyDataMongoDbTests {

    @Autowired
    private MongoTemplate mongoTemplate;

    // ...

}
```

内存中嵌入式 MongoDB 通常适用于测试，因为它速度快且不需要任何开发人员安装。但是，如果您更喜欢针对真正的 MongoDB 服务器运行测试，则应排除嵌入式 MongoDB 自动配置，如以下示例所示：

```java
@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
class MyDataMongoDbTests {

    // ...

}
```

7.&#x39;**.3.24. 自动配置的数据 Neo4j 测试**

`@DataNeo4jTest`用来测试 Neo4j 应用程序。默认情况下，它会扫描`@Node`类并配置 Spring Data Neo4j 存储库。使用注解 `@DataNeo4jTest`时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。（有关在 Spring Boot 中使用 Neo4J 的更多信息，请参阅“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.neo4j) ”。）

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) `@DataNeo4jTest`启用的自动配置设置列表。 以下示例显示了在 Spring Boot 中使用 Neo4J 测试的典型设置：

```java
@DataNeo4jTest
class MyDataNeo4jTests {

    @Autowired
    private SomeRepository repository;

    // ...

}
```

默认情况下，Data Neo4j 测试是事务性的，并在每次测试结束时回滚。有关更多详细信息，请参阅 Spring Framework 参考文档中的[相关部分](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/testing.html#testcontext-tx-enabling-transactions)。如果这不是您想要的，您可以为测试或整个类禁用事务管理，如下所示：

```java
@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyDataNeo4jTests {

}
```

反应式访问不支持事务测试。如果您使用此样式，则必须按上述方式配置`@DataNeo4jTest`测试。

7.&#x39;**.3.25. 自动配置的数据 Redis 测试**

`@DataRedisTest`用来测试 Redis 应用程序。默认情况下，它会扫描`@RedisHash`类并配置 Spring Data Redis 存储库。使用注解`@DataRedisTest`时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。。（有关在 Spring Boot 中使用 Redis 的更多信息，请参阅“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.redis) ”。）

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) `@DataRedisTest`启用的自动配置设置列表。 以下示例显示了`@DataRedisTest`正在使用的注解：

```java
@DataRedisTest
class MyDataRedisTests {

    @Autowired
    private SomeRepository repository;

    // ...

}
```

7.&#x39;**.3.26. 自动配置的数据 LDAP 测试**

您可以使用`@DataLdapTest`来测试 LDAP 应用程序。默认情况下，它配置内存中的嵌入式 LDAP（如果可用）、配置`LdapTemplate`、扫描`@Entry`类并配置 Spring Data LDAP 存储库。使用注解 `@DataLdapTest`时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。（有关在 Spring Boot 中使用 LDAP 的更多信息，请参阅“ [data.html](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.ldap) ”。）

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) `@DataLdapTest`启用的自动配置设置列表。 以下示例显示了`@DataLdapTest`正在使用的注解：

```java
@DataLdapTest
class MyDataLdapTests {

    @Autowired
    private LdapTemplate ldapTemplate;

    // ...

}
```

内存中嵌入式 LDAP 通常适用于测试，因为它速度快且不需要任何开发人员安装。但是，如果您更喜欢针对真实的 LDAP 服务器运行测试，则应排除嵌入式 LDAP 自动配置，如以下示例所示：

```java
@DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class)
class MyDataLdapTests {

    // ...

}
```

7.&#x39;**.3.27. 自动配置的 REST 客户端**

您可以使用`@RestClientTest`注解来测试 REST 客户端。默认情况下，它会自动配置 Jackson、GSON 和 Jsonb 支持，配置`RestTemplateBuilder`并添加`MockRestServiceServer`. 使用注解`@RestClientTest` 时不会扫描常规`@Component`和`@ConfigurationProperties`bean。`@EnableConfigurationProperties`可用于包含`@ConfigurationProperties`bean。

可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) `@RestClientTest`启用的自动配置设置列表。 您要测试的特定 bean 应使用`@RestClientTest` 的`value`或`components`属性指定，如以下示例所示：

```java
@RestClientTest(RemoteVehicleDetailsService.class)
class MyRestClientTests {

    @Autowired
    private RemoteVehicleDetailsService service;

    @Autowired
    private MockRestServiceServer server;

    @Test
    void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() {
        this.server.expect(requestTo("/greet/details")).andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
        String greeting = this.service.callRestService();
        assertThat(greeting).isEqualTo("hello");
    }

}
```

7.&#x39;**.3.28. 自动配置的 Spring REST 文档测试**

您可以使用`@AutoConfigureRestDocs`注解在您的测试中使用[Spring REST Docs](https://spring.io/projects/spring-restdocs)与 Mock MVC、REST Assured 或 WebTestClient。它消除了 Spring REST Docs 中对 JUnit 扩展的需求。

`@AutoConfigureRestDocs`可用于覆盖默认输出目录（如果您使用 Maven 默认是`target/generated-snippets`或使用 Gradle默认为`build/generated-snippets`）。它还可用于配置出现在任何记录的 URI 中的主机、方案和端口。

**使用 Mock MVC 自动配置 Spring REST 文档测试**

在测试基于 servlet 的 Web 应用程序时可以使用`@AutoConfigureRestDocs`自定义`MockMvc`bean 以使用 Spring REST Docs。您可以像使用 Mock MVC 和 Spring REST Docs 时一样在测试中使用和使用它，如以下示例所示：

```java
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
class MyUserDocumentationTests {

    @Autowired
    private MockMvc mvc;

    @Test
    void listUsers() throws Exception {
        this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
            .andExpect(status().isOk())
            .andDo(document("list-users"));
    }

}
```

如果您需要对 Spring REST Docs 配置的控制比`@AutoConfigureRestDocs`的属性提供的更多，则可以使用`RestDocsMockMvcConfigurationCustomizer`bean，如以下示例所示：

```java
@TestConfiguration(proxyBeanMethods = false)
public class MyRestDocsConfiguration implements RestDocsMockMvcConfigurationCustomizer {

    @Override
    public void customize(MockMvcRestDocumentationConfigurer configurer) {
        configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    }

}
```

如果你想利用 Spring REST Docs 对参数化输出目录的支持，你可以创建一个`RestDocumentationResultHandler`bean。使用此结果处理程序进行自动配置调用`alwaysDo`，从而导致每个`mockMvc`调用自动生成默认片段。下面的例子显示了一个被定义的`RestDocumentationResultHandler`：

```java
@TestConfiguration(proxyBeanMethods = false)
public class MyResultHandlerConfiguration {

    @Bean
    public RestDocumentationResultHandler restDocumentation() {
        return MockMvcRestDocumentation.document("{method-name}");
    }

}
```

**使用 WebTestClient 自动配置 Spring REST 文档测试**

也可以在测试响应式 Web 应用程序的`WebTestClient`时使用`@AutoConfigureRestDocs`。您可以像使用 Spring REST Docs 时一样在测试中使用`@WebFluxTest`和使用`@Autowired`，如以下示例所示：

```java
@WebFluxTest
@AutoConfigureRestDocs
class MyUsersDocumentationTests {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void listUsers() {
        this.webTestClient
            .get().uri("/")
        .exchange()
        .expectStatus()
            .isOk()
        .expectBody()
            .consumeWith(document("list-users"));
    }

}
```

如果您需要对 Spring REST Docs 配置的控制比 的属性提供的更多`@AutoConfigureRestDocs`，则可以使用`RestDocsWebTestClientConfigurationCustomizer`bean，如以下示例所示：

```java
@TestConfiguration(proxyBeanMethods = false)
public class MyRestDocsConfiguration implements RestDocsWebTestClientConfigurationCustomizer {

    @Override
    public void customize(WebTestClientRestDocumentationConfigurer configurer) {
        configurer.snippets().withEncoding("UTF-8");
    }

}
```

如果您想利用 Spring REST Docs 对参数化输出目录的支持，您可以使用 `WebTestClientBuilderCustomizer`为每个实体交换结果配置消费者。以下示例显示了这样的`WebTestClientBuilderCustomizer`定义：

```java
@TestConfiguration(proxyBeanMethods = false)
public class MyWebTestClientBuilderCustomizerConfiguration {

    @Bean
    public WebTestClientBuilderCustomizer restDocumentation() {
        return (builder) -> builder.entityExchangeResultConsumer(document("{method-name}"));
    }

}
```

**带有 REST Assured 的自动配置 Spring REST 文档测试**

`@AutoConfigureRestDocs`使预配置为使用 Spring REST Docs 的`RequestSpecification` bean 可用于您的测试。您可以像使用 REST Assured 和 Spring REST Docs 时一样在测试中使用`@Autowired`和使用它，如以下示例所示：

```java
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs
class MyUserDocumentationTests {

    @Test
    void listUsers(@Autowired RequestSpecification documentationSpec, @LocalServerPort int port) {
        given(documentationSpec)
            .filter(document("list-users"))
        .when()
            .port(port)
            .get("/")
        .then().assertThat()
            .statusCode(is(200));
    }

}
```

如果您需要对 Spring REST Docs 配置的控制比`@AutoConfigureRestDocs`的属性提供的更多，则可以使用`RestDocsRestAssuredConfigurationCustomizer` bean，如以下示例所示：

```java
@TestConfiguration(proxyBeanMethods = false)
public class MyRestDocsConfiguration implements RestDocsRestAssuredConfigurationCustomizer {

    @Override
    public void customize(RestAssuredRestDocumentationConfigurer configurer) {
        configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    }

}
```

7.&#x39;**.3.29. 自动配置的 Spring Web 服务测试**

**自动配置的 Spring Web 服务客户端测试**

您可以使用 `@WebServiceClientTest` 来测试使用 Spring Web Services 项目实现 Web 服务的应用程序。默认情况下，它配置一个模拟`WebServiceServer`bean 并自动自定义您的`WebServiceTemplateBuilder`. （有关在 Spring Boot 中使用 Web 服务的更多信息，请参阅“ [io.html](https://docs.spring.io/spring-boot/docs/current/reference/html/io.html#io.webservices) ”。） 可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration)`@WebServiceClientTest` 启用的自动配置设置列表。 以下示例显示了`@WebServiceClientTest`正在使用的注解：

```java
@WebServiceClientTest(SomeWebService.class)
class MyWebServiceClientTests {

    @Autowired
    private MockWebServiceServer server;

    @Autowired
    private SomeWebService someWebService;

    @Test
    void mockServerCall() {
        this.server
            .expect(payload(new StringSource("<request/>")))
            .andRespond(withPayload(new StringSource("<response><status>200</status></response>")));
        assertThat(this.someWebService.test())
            .extracting(Response::getStatus)
            .isEqualTo(200);
    }

}
```

**自动配置的 Spring Web 服务服务器测试**

您可以使用 `@WebServiceServerTest` 来测试使用 Spring Web Services 项目实现 Web 服务的应用程序。默认情况下，它配置一个可用于调用 Web 服务端点的 `MockWebServiceClient`bean。（有关在 Spring Boot 中使用 Web 服务的更多信息，请参阅“ [io.html](https://docs.spring.io/spring-boot/docs/current/reference/html/io.html#io.webservices) ”。） 可[在附录中找到](https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html#appendix.test-auto-configuration) `@WebServiceServerTest`启用的自动配置设置列表。 以下示例显示了`@WebServiceServerTest`正在使用的注解：

```java
@WebServiceServerTest(ExampleEndpoint.class)
class MyWebServiceServerTests {

    @Autowired
    private MockWebServiceClient client;

    @Test
    void mockServerCall() {
        this.client
            .sendRequest(RequestCreators.withPayload(new StringSource("<ExampleRequest/>")))
            .andExpect(ResponseMatchers.payload(new StringSource("<ExampleResponse>42</ExampleResponse>")));
    }

}
```

7.&#x39;**.3.30. 额外的自动配置和切面**

每个切面提供一个或多个`@AutoConfigure…`注解，即定义应作为切面一部分包含的自动配置。通过创建自定义`@AutoConfigure…`注解或通过`@ImportAutoConfiguration`添加到测试中，可以逐个测试添加其他自动配置，如以下示例所示：

```java
@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
class MyJdbcTests {

}
```

确保不要使用常规`@Import`注解来导入自动配置，因为它们是由 Spring Boot 以特定方式处理的。 或者，可以为切面注解的任何使用添加额外的自动配置，方法是将它们注册到存储的`META-INF/spring`文件中，如以下示例所示： META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.JdbcTest.imports

```
com.example.IntegrationAutoConfiguration
```

在此示例中，在`com.example.IntegrationAutoConfiguration`使用 注解的每个测试上都启用了`@JdbcTest`。

您可以通过在此文件中使用`#`注解。

切片或@AutoConfigure ...注释可以通过这种方式自定义，只要它使用@ImportAutoConfiguration进行元注释即可。

7.&#x39;**.3.31. 用户配置和切面**

如果您以合理的方式[构建代码，则](https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.structuring-your-code)[默认情况下](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.detecting-configuration)您的`@SpringBootApplication`类将用作测试的配置。

然后，重要的是不要在应用程序的主类中乱扔特定于其功能特定区域的配置设置。

假设您使用的是 Spring Batch，并且您依赖于它的自动配置。您可以定义`@SpringBootApplication`如下：

```java
@SpringBootApplication
@EnableBatchProcessing
public class MyApplication {

    // ...

}
```

因为这个类是测试的源配置，所以任何切面测试实际上都会尝试启动 Spring Batch，这绝对不是你想要做的。推荐的方法是将特定于区域的配置移动到与您的应用程序处于同一级别的单独`@Configuration`类中，如以下示例所示：

```java
@Configuration(proxyBeanMethods = false)
@EnableBatchProcessing
public class MyBatchConfiguration {

    // ...

}
```

根据您的应用程序的复杂性，您可能有一个用于自定义的类或每个域区域一个`@Configuration`类。后一种方法允许您在其中一个测试中启用它，如有必要，使用`@Import`注解。有关何时可能希望为切面测试启用特定类的 `@Configuration`更多详细信息，请参阅[此操作指南部分。](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.testing.slice-tests) 测试切面将`@Configuration`类排除在扫描之外。例如，对于 `@WebMvcTest`，以下配置不会在测试切面加载的应用程序上下文中包含给定的`WebMvcConfigurer` bean：

```java
@Configuration(proxyBeanMethods = false)
public class MyWebConfiguration {

    @Bean
    public WebMvcConfigurer testConfigurer() {
        return new WebMvcConfigurer() {
            // ...
        };
    }

}
```

但是，下面的配置将导致自定义`WebMvcConfigurer`被测试切面加载。

```java
@Component
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    // ...

}
```

另一个混淆来源是类路径扫描。假设，当您以合理的方式构建代码时，您需要扫描一个额外的包。您的应用程序可能类似于以下代码：

```java
@SpringBootApplication
@ComponentScan({ "com.example.app", "com.example.another" })
public class MyApplication {

    // ...

}
```

这样做有效地覆盖了默认的组件扫描指令，其副作用是扫描这两个包，而不管您选择的切面是什么。例如，a`@DataJpaTest`似乎突然扫描应用程序的组件和用户配置。同样，将自定义指令移动到单独的类是解决此问题的好方法。

如果这不是您的选择，您可以`@SpringBootConfiguration`在测试的层次结构中创建一个位置，以便使用它。或者，您可以为您的测试指定一个源，这将禁用查找默认源的行为。

7.&#x39;**.3.32. 使用 Spock 测试 Spring Boot 应用程序**

Spock 2.x 可用于测试 Spring Boot 应用程序。为此，请将 Spock`spock-spring`模块的依赖项添加到应用程序的构建中。 `spock-spring`将 Spring 的测试框架集成到 Spock 中。有关详细信息，请参阅[Spock 的 Spring 模块的文档](https://spockframework.org/spock/docs/2.0/modules.html#_spring_module)。
