Spring Boot提供了许多实用程序和注释,可以在测试应用程序时提供帮助。测试支持由两个模块提供:spring-boot-test包含核心项,并spring-boot-test-autoconfigure支持测试的自动配置。
    大多数开发人员都使用spring-boot-starter-test“入门程序”,该程序同时导入Spring Boot测试模块以及JUnit Jupiter,AssertJ,Hamcrest和许多其他有用的库。

    | | 如果您有使用JUnit 4的测试,则可以使用JUnit 5的老式引擎来运行它们。要使用老式引擎,请添加对的依赖junit-vintage-engine,如以下示例所示:```

    org.junit.vintage junit-vintage-engine test org.hamcrest hamcrest-core

    1. |
    2. | :---: | --- |
    3. `hamcrest-core`被排除在外`org.hamcrest:hamcrest`,是的一部分`spring-boot-starter-test`
    4. <a name="boot-features-test-scope-dependencies"></a>
    5. ### 26.1 测试范围依赖性
    6. `spring-boot-starter-test`“入门”(中`test` `scope`)包含以下提供的库:
    7. - [JUnit 5](https://junit.org/junit5/):用于对Java应用程序进行单元测试的事实上的标准。
    8. - [Spring Test](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#integration-testing)和Spring Boot Test:对Spring Boot应用程序的实用程序和集成测试支持。
    9. - [AssertJ](https://assertj.github.io/doc/):流畅的断言库。
    10. - [Hamcrest](https://github.com/hamcrest/JavaHamcrest):匹配对象库(也称为约束或谓词)。
    11. - [Mockito](https://site.mockito.org/):一个Java[模拟](https://site.mockito.org/)框架。
    12. - [JSONassert](https://github.com/skyscreamer/JSONassert):JSON的断言库。
    13. - [JsonPath](https://github.com/jayway/JsonPath):JSON的XPath。
    14. 通常,我们发现这些通用库在编写测试时很有用。如果这些库不适合您的需求,则可以添加自己的其他测试依赖项。
    15. <a name="boot-features-testing-spring-applications"></a>
    16. ### 26.2 测试Spring应用程序
    17. 依赖注入的主要优点之一是,它应该使您的代码更易于进行单元测试。您可以使用`new`运算符实例化对象,甚至不需要使用Spring。您还可以使用_模拟对象_而不是实际的依赖项。<br />通常,您需要超越单元测试并开始集成测试(使用Spring `ApplicationContext`)。能够进行集成测试而无需部署应用程序或连接到其他基础结构,这很有用。<br />Spring框架包括用于此类集成测试的专用测试模块。您可以直接向其声明依赖项,`org.springframework:spring-test`也可以使用`spring-boot-starter-test`“启动器”将其引入。<br />如果您以前没有使用过该`spring-test`模块,则应先阅读Spring Framework参考文档的[相关部分](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#testing)。
    18. <a name="boot-features-testing-spring-boot-applications"></a>
    19. ### 26.3 测试Spring Boot应用程序
    20. Spring Boot应用程序是Spring `ApplicationContext`,因此除了对普通Spring上下文进行常规测试以外,无需执行任何其他特殊操作即可对其进行测试。
    21. | | 默认情况下,Spring Boot的外部属性,日志记录和其他功能仅在`SpringApplication`用于创建时才安装在上下文中。 |
    22. | :---: | --- |
    23. Spring Boot提供了一个`@SpringBootTest`注释,`spring-test` `@ContextConfiguration`当您需要Spring Boot功能时,它可以用作标准注释的替代。注释通过[创建`ApplicationContext`在测试中使用的来`SpringApplication`](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-detecting-config)起作用。除了`@SpringBootTest`提供许多其他注释,还用于[测试](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-tests)应用程序的[更多特定](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-tests)部分。
    24. | | 如果使用的是JUnit 4,请不要忘记也将其添加`@RunWith(SpringRunner.class)`到测试中,否则注释将被忽略。如果您使用的是JUnit 5,则无需添加等价物`@ExtendWith(SpringExtension.class)``@SpringBootTest`并且其他`@…Test`注释已经使用它进行了注释。 |
    25. | :---: | --- |
    26. 默认情况下,`@SpringBootTest`不会启动服务器。您可以使用的`webEnvironment`属性`@SpringBootTest`进一步完善测试的运行方式:
    27. - `MOCK`(默认):加载Web`ApplicationContext`并提供模拟Web环境。使用此注释时,不会启动嵌入式服务器。如果您的类路径中没有网络环境,则此模式将透明地退回到创建常规非网络`ApplicationContext`。它可以与Web应用程序结合使用[`@AutoConfigureMockMvc``@AutoConfigureWebTestClient`](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-mock-environment)用于基于模拟的测试。
    28. - `RANDOM_PORT`:加载`WebServerApplicationContext`并提供真实的网络环境。嵌入式服务器将启动并在随机端口上侦听。
    29. - `DEFINED_PORT`:加载`WebServerApplicationContext`并提供真实的网络环境。嵌入式服务器将启动并在已定义的端口(来自`application.properties`)上或在的默认端口上进行侦听`8080`
    30. - `NONE``ApplicationContext`通过使用加载,`SpringApplication`但不提供_任何_网络环境(模拟或其他方式)。
    31. | | 如果您的测试是`@Transactional`,则默认情况下它将在每个测试方法的末尾回滚事务。但是,由于将这种安排与一个`RANDOM_PORT`或多个`DEFINED_PORT`隐式提供真实的servlet环境一起使用,HTTP客户端和服务器在单独的线程中运行,因此在单独的事务中运行。在这种情况下,服务器上启动的任何事务都不会回滚。 |
    32. | :---: | --- |
    33. | | `@SpringBootTest``webEnvironment = WebEnvironment.RANDOM_PORT`如果您的应用程序对管理服务器使用其他端口,则with还将在单独的随机端口上启动管理服务器。 |
    34. | :---: | --- |
    35. <a name="boot-features-testing-spring-boot-applications-detecting-web-app-type"></a>
    36. #### 26.3.1 检测Web应用程序类型
    37. 如果Spring MVC可用,则配置基于常规MVC的应用程序上下文。如果您只有Spring WebFlux,我们将检测到该情况并配置基于WebFlux的应用程序上下文。<br />如果两者都存在,则Spring MVC优先。如果要在这种情况下测试反应式Web应用程序,则必须设置`spring.main.web-application-type`属性:

    @SpringBootTest(properties = “spring.main.web-application-type=reactive”) class MyWebFluxTests { … }

    1. <a name="boot-features-testing-spring-boot-applications-detecting-config"></a>
    2. #### 26.3.2 检测测试配置
    3. 如果您熟悉Spring Test Framework,则可能习惯于使用`@ContextConfiguration(classes=…)`来指定`@Configuration`要加载哪个Spring 。另外,您可能经常`@Configuration`在测试中使用嵌套类。<br />在测试Spring Boot应用程序时,通常不需要这样做。`@*Test`只要您没有明确定义Spring Boot的注释,它就会自动搜索您的主要配置。<br />搜索算法从包含测试的程序包开始工作,直到找到带有`@SpringBootApplication`或注释的类`@SpringBootConfiguration`。只要您以合理的方式[对代码](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/using-spring-boot.html#using-boot-structuring-your-code)进行[结构化](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/using-spring-boot.html#using-boot-structuring-your-code),通常就可以找到您的主要配置。
    4. | | 如果使用[测试注释来测试应用程序的更特定的部分](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-tests),则应避免在[main方法的应用程序类](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-user-configuration)上添加特定于特定区域的配置设置。<br />define的基础组件扫描配置`@SpringBootApplication`排除了用于确保切片按预期工作的过滤器。如果`@ComponentScan`在`@SpringBootApplication`-annotated类上使用显式指令,请注意这些过滤器将被禁用。如果使用切片,则应重新定义它们。 |
    5. | :---: | --- |
    6. 如果要自定义主要配置,则可以使用嵌套`@TestConfiguration`类。与`@Configuration`将使用嵌套类代替应用程序的主要配置的嵌套`@TestConfiguration`类不同,除了应用程序的主要配置之外,还使用了嵌套类。
    7. | | Spring的测试框架在测试之间缓存应用程序上下文。因此,只要您的测试共享相同的配置(无论如何发现),加载上下文的潜在耗时过程就只会发生一次。 |
    8. | :---: | --- |
    9. <a name="boot-features-testing-spring-boot-applications-excluding-config"></a>
    10. #### 26.3.3 排除测试配置
    11. 如果您的应用程序使用组件扫描(例如,如果使用`@SpringBootApplication`或`@ComponentScan`),则可能会偶然发现到处仅为特定测试创建的顶级配置类。<br />如我们[先前所见](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-detecting-config),`@TestConfiguration`可以在测试的内部类上使用来自定义主要配置。当放置在顶级类上时,`@TestConfiguration`指示`src/test/java`不应通过扫描来拾取其中的类。然后,可以在需要的位置显式导入该类,如以下示例所示:

    @SpringBootTest @Import(MyTestsConfiguration.class) class MyTests { @Test void exampleTest() { … } }

    1. | | 如果您直接使用`@ComponentScan`(即不是通过`@SpringBootApplication`),则需要向其注册`TypeExcludeFilter`。有关详细信息,请参见[Javadoc](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/api/org/springframework/boot/context/TypeExcludeFilter.html)。 |
    2. | :---: | --- |
    3. <a name="boot-features-testing-spring-boot-application-arguments"></a>
    4. #### 26.3.4 使用应用程序参数
    5. 如果您的应用程序需要[参数](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-application-arguments),则可以`@SpringBootTest`使用`args`属性注入它们。

    @SpringBootTest(args = “—app.test=one”) class ApplicationArgumentsExampleTests { @Test void applicationArgumentsPopulated(@Autowired ApplicationArguments args) { assertThat(args.getOptionNames()).containsOnly(“app.test”); assertThat(args.getOptionValues(“app.test”)).containsOnly(“one”); } }

    1. <a name="boot-features-testing-spring-boot-applications-testing-with-mock-environment"></a>
    2. #### 26.3.5 在模拟环境中进行测试
    3. 默认情况下,`@SpringBootTest`不启动服务器。如果您有要在此模拟环境下进行测试的Web终结点,则可以另外配置[`MockMvc`](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#spring-mvc-test-framework),如以下示例所示:

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @AutoConfigureMockMvc class MockMvcExampleTests { @Test void exampleTest(@Autowired MockMvc mvc) throws Exception { mvc.perform(get(“/“)).andExpect(status().isOk()).andExpect(content().string(“Hello World”)); } }

    1. | | 如果您只想专注于Web层而不希望完全完成`ApplicationContext`,请考虑[使用`@WebMvcTest`代替](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests)。 |
    2. | :---: | --- |
    3. 或者,您可以配置[`WebTestClient`](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#webtestclient-tests),如以下示例所示:

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; @SpringBootTest @AutoConfigureWebTestClient class MockWebTestClientExampleTests { @Test void exampleTest(@Autowired WebTestClient webClient) { webClient.get().uri(“/“).exchange().expectStatus().isOk().expectBody(String.class).isEqualTo(“Hello World”); } }

    1. | | 在模拟环境中进行测试通常比在完整的Servlet容器中运行更快。但是,由于模拟是在Spring MVC层进行的,因此无法使用MockMvc直接测试依赖于较低级别Servlet容器行为的代码。<br />例如,Spring Boot的错误处理基于Servlet容器提供的“错误页面”支持。这意味着,尽管您可以按预期测试MVC层引发并处理异常,但是您无法直接测试是否呈现了特定的[自定义错误页面](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-error-handling-custom-error-pages)。如果您需要测试这些较低级别的问题,则可以按照下一节中的描述启动一个完全运行的服务器。 |
    2. | :---: | --- |
    3. <a name="boot-features-testing-spring-boot-applications-testing-with-running-server"></a>
    4. #### 26.3.6 使用正在运行的服务器进行测试
    5. 如果需要启动完全运行的服务器,建议您使用随机端口。如果使用`@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)`,则每次运行测试时都会随机选择一个可用端口。<br />该`@LocalServerPort`注释可用于[注射使用的实际端口](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/howto.html#howto-discover-the-http-port-at-runtime)到您的测试。为了方便起见,需要对启动的服务器进行REST调用的测试可以另外`@Autowire`使用[`WebTestClient`](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#webtestclient-tests),它解析到正在运行的服务器的相对链接,并带有用于验证响应的专用API,如以下示例所示:

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.web.reactive.server.WebTestClient; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class RandomPortWebTestClientExampleTests { @Test void exampleTest(@Autowired WebTestClient webClient) { webClient.get().uri(“/“).exchange().expectStatus().isOk().expectBody(String.class).isEqualTo(“Hello World”); } }

    1. 此设置需要`spring-webflux`在类路径上进行。如果您不能或不会添加webfluxSpring Boot还提供了以下`TestRestTemplate`功能:

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class RandomPortTestRestTemplateExampleTests { @Test void exampleTest(@Autowired TestRestTemplate restTemplate) { String body = restTemplate.getForObject(“/“, String.class); assertThat(body).isEqualTo(“Hello World”); } }

    1. <a name="boot-features-testing-spring-boot-applications-customizing-web-test-client"></a>
    2. #### 26.3.7 自定义WebTestClient
    3. 要自定义`WebTestClient`Bean,请配置`WebTestClientBuilderCustomizer`Bean。`WebTestClient.Builder`会使用用于创建的任何此类bean进行调用`WebTestClient`。
    4. <a name="boot-features-testing-spring-boot-applications-jmx"></a>
    5. #### 26.3.8 使用JMX
    6. 由于测试上下文框架缓存上下文,因此默认情况下禁用JMX以防止相同组件在同一域上注册。如果此类测试需要访问`MBeanServer`,请考虑将其标记为脏:

    @ExtendWith(SpringExtension.class) @SpringBootTest(properties = “spring.jmx.enabled=true”) @DirtiesContext class SampleJmxTests { @Autowired private MBeanServer mBeanServer; @Test void exampleTest() { // … } }

    1. <a name="boot-features-testing-spring-boot-applications-metrics"></a>
    2. #### 26.3.9 使用指标
    3. 无论使用哪种类路径,使用时都不会自动配置电表注册表(内存中支持的除外)`@SpringBootTest`。<br />如果您需要在集成测试中将指标导出到其他后端,请使用进行注释`@AutoConfigureMetrics`。
    4. <a name="boot-features-testing-spring-boot-applications-mocking-beans"></a>
    5. #### 26.3.10 模拟豆和间谍豆
    6. 运行测试时,有时有必要在应用程序上下文中模拟某些组件。例如,您可能在开发期间无法使用某些远程服务的外观。当您要模拟在实际环境中可能难以触发的故障时,模拟功能也很有用。<br />Spring Boot包含一个`@MockBean`注释,可用于为您的Bean中的bean定义Mockito模拟`ApplicationContext`。您可以使用注释添加新的bean或替换单个现有的bean定义。注释可以直接用于测试类,测试中的字段或`@Configuration`类和字段。当在字段上使用时,还将注入创建的模拟的实例。每种测试方法后,模拟豆都会自动重置。
    7. | | 如果您的测试使用Spring Boot的测试注释之一(例如`@SpringBootTest`),则此功能会自动启用。要以其他方式使用此功能,必须显式添加侦听器,如以下示例所示:

    @TestExecutionListeners(MockitoTestExecutionListener.class)

    1. |
    2. | :---: | --- |
    3. 下面的示例用`RemoteService`模拟实现替换现有的bean

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.; import org.springframework.boot.test.context.; import org.springframework.boot.test.mock.mockito.; import static org.assertj.core.api.Assertions.; import static org.mockito.BDDMockito.*; @SpringBootTest class MyTests { @MockBean private RemoteService remoteService; @Autowired private Reverser reverser; @Test void exampleTest() { // RemoteService has been injected into the reverser bean given(this.remoteService.someCall()).willReturn(“mock”); String reverse = reverser.reverseSomeCall(); assertThat(reverse).isEqualTo(“kcom”); } }

    1. | | `@MockBean`不能用来模拟应用程序上下文刷新期间执行的bean的行为。到执行测试时,应用程序上下文刷新已完成,并且配置模拟行为为时已晚。我们建议`@Bean`在这种情况下使用一种方法来创建和配置模拟。 |
    2. | :---: | --- |
    3. 另外,您可以使用`@SpyBean`Mockito来包装任何现有的bean `spy`。有关完整的详细信息,请参见[Javadoc](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/api/org/springframework/boot/test/mock/mockito/SpyBean.html)。
    4. | | CGLib代理(例如为范围内的bean创建的代理)将代理方法声明为`final`。这会阻止Mockito正常运行,因为它无法模拟或监视`final`其默认配置中的方法。如果要模拟或监视此类bean,请通过添加`org.mockito:mockito-inline`到应用程序的测试依赖项中,将Mockito配置为使用其内联模拟生成器。这允许Mockito模拟和监视`final`方法。 |
    5. | :---: | --- |
    6. | | Spring的测试框架在测试之间缓存应用程序上下文,并为共享相同配置的测试重用上下文,但是缓存密钥的使用`@MockBean``@SpyBean`影响缓存密钥,这很可能会增加上下文的数量。 |
    7. | :---: | --- |
    8. | | 如果您使用`@SpyBean`带有`@Cacheable`通过名称引用参数的方法来监视Bean,则必须使用编译应用程序`-parameters`。这样可以确保一旦侦察到bean,就可以将参数名称用于缓存基础结构。 |
    9. | :---: | --- |
    10. | | 当您`@SpyBean`用来监视由Spring代理的bean时,在某些情况下,例如使用`given`或设置期望值时,可能需要删除Spring的代理`when`。使用`AopTestUtils.getTargetObject(yourProxiedSpy)`这样做。 |
    11. | :---: | --- |
    12. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-tests"></a>
    13. #### 26.3.11 自动配置的测试
    14. Spring Boot的自动配置系统适用于应用程序,但有时对于测试而言可能有点过多。它通常仅有助于加载测试应用程序“切片”所需的配置部分。例如,您可能想要测试Spring MVC控制器是否正确映射了URL,并且您不想在这些测试中涉及数据库调用,或者您想要测试JPA实体,并且对那些JPA实体不感兴趣。测试运行。<br />该`spring-boot-test-autoconfigure`模块包括许多注释,可用于自动配置此类“切片”。它们中的每一个都以类似的方式工作,提供了一个`@…Test`加载的注释`ApplicationContext`以及一个或多个`@AutoConfigure…`可用于自定义自动配置设置的注释。
    15. | | 每个切片将组件扫描限制为适当的组件,并加载一组非常受限制的自动配置类。如果您需要排除其中之一,则大多数`@…Test`注释都提供一个`excludeAutoConfiguration`属性。或者,您可以使用`@ImportAutoConfiguration#exclude` |
    16. | :---: | --- |
    17. | | `@…Test`不支持在一个测试中 使用多个注释来包含多个“片段” 。如果需要多个“切片”,请选择其中一个`@…Test`注释,并`@AutoConfigure…`手动添加其他“切片”的注释。 |
    18. | :---: | --- |
    19. | | 也可以将`@AutoConfigure…`注释与标准`@SpringBootTest`注释一起使用。如果您对“切片”应用程序不感兴趣,但需要一些自动配置的测试bean,则可以使用此组合。 |
    20. | :---: | --- |
    21. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-json-tests"></a>
    22. #### 26.3.12 自动配置的JSON测试
    23. 要测试对象JSON序列化和反序列化是否按预期工作,可以使用`@JsonTest`批注。 `@JsonTest`自动配置可用的受支持的JSON映射器,该映射器可以是以下库之一:
    24. - 杰克逊`ObjectMapper`,任何`@JsonComponent`豆子和任何杰克逊`Module`
    25. - `Gson`
    26. - `Jsonb`
    27. | | 由启用了自动配置的列表`@JsonTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    28. | :---: | --- |
    29. 如果需要配置自动配置的元素,则可以使用`@AutoConfigureJsonTesters`注释。<br />Spring Boot包括基于AssertJ的助手,这些助手与JSONAssertJsonPath库一起使用,以检查JSON是否按预期方式显示。的`JacksonTester``GsonTester``JsonbTester`,和`BasicJsonTester`类可以分别用于杰克逊,GSONJsonb,和字符串。`@Autowired`使用时,可以在测试类上使用任何帮助程序字段`@JsonTest`。以下示例显示了Jackson的测试类:

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.; import org.springframework.boot.test.autoconfigure.json.; import org.springframework.boot.test.context.; import org.springframework.boot.test.json.; import static org.assertj.core.api.Assertions.*; @JsonTest class MyJsonTests { @Autowired private JacksonTester json; @Test void testSerialize() 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 testDeserialize() 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”); } }

    1. | | JSON帮助程序类也可以直接在标准单元测试中使用。为此,如果不使用,请`initFields`在您的`@Before`方法中调用辅助方法`@JsonTest` |
    2. | :---: | --- |
    3. 如果您正在使用基于Spring Boot的基于AssertJ的助手来声明给定JSON路径上的数字值,则可能无法使用,`isEqualTo`具体取决于类型。相反,您可以使用AssertJ`satisfies`声明该值匹配给定条件。例如,以下示例断言实际数字是一个接近于`0.15`偏移量内的浮点值`0.01`

    assertThat(json.write(message)) .extractingJsonPathNumberValue(“@.test.numberValue”) .satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests"></a>
    2. #### 26.3.13 自动配置的Spring MVC测试
    3. 要测试Spring MVC控制器是否按预期工作,请使用`@WebMvcTest`注释。 `@WebMvcTest`自动配置Spring MVC的基础设施和限制扫描豆`@Controller`,`@ControllerAdvice`,`@JsonComponent`,`Converter`,`GenericConverter`,`Filter`,`HandlerInterceptor`,`WebMvcConfigurer`,和`HandlerMethodArgumentResolver`。使用注解时,不会扫描Regular`@Component`和`@ConfigurationProperties`bean `@WebMvcTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。
    4. | | 的由启用了自动配置设置列表`@WebMvcTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    5. | :---: | --- |
    6. | | 如果需要注册其他组件,例如Jackson `Module`,则可以`@Import`在测试中使用来导入其他配置类。 |
    7. | :---: | --- |
    8. 通常,`@WebMvcTest`它仅限于单个控制器,并且与之结合使用`@MockBean`以为所需的协作者提供模拟实现。<br />`@WebMvcTest`也可以自动配置`MockMvc`。Mock MVC提供了一种强大的方法来快速测试MVC控制器,而无需启动完整的HTTP服务器。
    9. | | 您还可以通过使用注释`MockMvc`在非`@WebMvcTest`(例如`@SpringBootTest`)中进行自动配置`@AutoConfigureMockMvc`。以下示例使用`MockMvc`: |
    10. | :---: | --- |

    import org.junit.jupiter.api.; import org.springframework.beans.factory.annotation.; import org.springframework.boot.test.autoconfigure.web.servlet.; import org.springframework.boot.test.mock.mockito.; import static org.assertj.core.api.Assertions.; import static org.mockito.BDDMockito.; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.; @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”)); } }

    1. | | 如果您需要配置自动配置的元素(例如,当应该应用servlet过滤器时),则可以在`@AutoConfigureMockMvc`注释中使用属性。 |
    2. | :---: | --- |
    3. 如果使用HtmlUnitSelenium,则自动配置还会提供HtmlUnit `WebClient`bean和/或Selenium `WebDriver`bean。以下示例使用HtmlUnit

    import com.gargoylesoftware.htmlunit.; import org.junit.jupiter.api.; import org.springframework.beans.factory.annotation.; import org.springframework.boot.test.autoconfigure.web.servlet.; import org.springframework.boot.test.mock.mockito.; import static org.assertj.core.api.Assertions.; import static org.mockito.BDDMockito.*; @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”); } }

    1. | | 默认情况下,Spring Boot`WebDriver`bean放在一个特殊的“作用域”中,以确保驱动程序在每次测试后退出并注入新实例。如果您不希望出现这种情况,可以将其添加`@Scope("singleton")``WebDriver` `@Bean`定义中。 |
    2. | :---: | --- |
    3. | | `webDriver`Spring Boot创建 的作用域将替换任何具有相同名称的用户定义的作用域。如果您定义自己的`webDriver`范围,则可能会发现它在使用时停止工作`@WebMvcTest` |
    4. | :---: | --- |
    5. 如果您在类路径上具有Spring Security`@WebMvcTest`还将扫描`WebSecurityConfigurer`bean。您可以使用Spring Security的测试支持,而不是完全禁用此类测试的安全性。有关如何使用Spring Security`MockMvc`支持的更多详细信息,请参见_[howto.html操作](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/howto.html#howto-use-test-with-spring-security)_方法部分。
    6. | | 有时编写Spring MVC测试是不够的。Spring Boot可以帮助您[使用实际服务器](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server)运行[完整的端到端测试](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server)。 |
    7. | :---: | --- |
    8. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-webflux-tests"></a>
    9. #### 26.3.14 自动配置的Spring WebFlux测试
    10. 要测试[Spring WebFlux](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/web-reactive.html)控制器是否按预期工作,可以使用`@WebFluxTest`注释。 `@WebFluxTest`自动配置春季WebFlux基础设施和限制扫描豆`@Controller`,`@ControllerAdvice`,`@JsonComponent`,`Converter`,`GenericConverter`,`WebFilter`,和`WebFluxConfigurer`。使用注解时,不会扫描Regular`@Component`和`@ConfigurationProperties`bean `@WebFluxTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。
    11. | | 由启用了自动配置的列表`@WebFluxTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    12. | :---: | --- |
    13. | | 如果您需要注册其他组件,例如Jackson `Module`,则可以`@Import`在测试中使用导入其他配置类。 |
    14. | :---: | --- |
    15. 通常,`@WebFluxTest`它仅限于单个控制器,并且与`@MockBean`注释结合使用以为所需的协作者提供模拟实现。<br />`@WebFluxTest`还自动配置[`WebTestClient`](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#webtestclient),它提供了一种强大的方法来快速测试WebFlux控制器,而无需启动完整的HTTP服务器。
    16. | | 您还可以通过使用注释`WebTestClient`在非`@WebFluxTest`(例如`@SpringBootTest`)中进行自动配置`@AutoConfigureWebTestClient`。以下示例显示了同时使用`@WebFluxTest`和的类`WebTestClient` |
    17. | :---: | --- |

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; @WebFluxTest(UserVehicleController.class) class MyControllerTests { @Autowired private WebTestClient webClient; @MockBean private UserVehicleService userVehicleService; @Test void testExample() throws Exception { 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”); } }

    1. | | WebFlux应用程序仅支持此设置,因为`WebTestClient`在模拟Web应用程序中使用的设置目前仅适用于WebFlux |
    2. | :---: | --- |
    3. | | `@WebFluxTest`无法检测通过功能Web框架注册的路由。要`RouterFunction`在上下文中测试Bean,请考虑`RouterFunction`通过`@Import`或使用导入自己`@SpringBootTest` |
    4. | :---: | --- |
    5. | | `@WebFluxTest`无法检测到通过`@Bean`类型注册的自定义安全配置`SecurityWebFilterChain`。要将其包括在测试中,您将需要通过`@Import`或使用导入注册Bean的配置`@SpringBootTest` |
    6. | :---: | --- |
    7. | | 有时编写Spring WebFlux测试是不够的。Spring Boot可以帮助您[使用实际服务器](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server)运行[完整的端到端测试](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server)。 |
    8. | :---: | --- |
    9. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-cassandra-test"></a>
    10. #### 16.3.15 自动配置的数据Cassandra测试
    11. 您可以`@DataCassandraTest`用来测试Cassandra应用程序。默认情况下,它配置一个`CassandraTemplate`,扫描`@Table`类,并配置Spring Data Cassandra存储库。使用注解时,不会扫描Regular`@Component``@ConfigurationProperties`bean `@DataCassandraTest` `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。(有关在Spring Boot中结合使用Cassandra的更多信息,请参阅本章前面的“ [Cassandra](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-cassandra) ”。)
    12. | | 的由启用了自动配置设置列表`@DataCassandraTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    13. | :---: | --- |
    14. 以下示例显示了在Spring Boot中使用Cassandra测试的典型设置:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest; @DataCassandraTest class ExampleDataCassandraTests { @Autowired private YourRepository repository; // }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test"></a>
    2. #### 26.3.16 自动配置的数据JPA测试
    3. 您可以使用`@DataJpaTest`注释来测试JPA应用程序。默认情况下,它会扫描`@Entity`类并配置Spring Data JPA存储库。如果在类路径上有嵌入式数据库,它也会配置一个。使用注解时,不会扫描Regular`@Component`和`@ConfigurationProperties`bean `@DataJpaTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。
    4. | | 的由启用了自动配置设置列表`@DataJpaTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    5. | :---: | --- |
    6. 默认情况下,数据JPA测试是事务性的,并在每次测试结束时回滚。有关更多详细信息,请参见Spring Framework参考文档中的[相关部分](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#testcontext-tx-enabling-transactions)。如果这不是您想要的,则可以按以下方式禁用测试或整个类的事务管理:

    import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @DataJpaTest @Transactional(propagation = Propagation.NOT_SUPPORTED) class ExampleNonTransactionalTests { }

    1. 数据JPA测试也可以注入[`TestEntityManager`](https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/TestEntityManager.java)Bean,这`EntityManager`是专门为测试设计的标准JPA的替代方法。如果要`TestEntityManager`在`@DataJpaTest`实例外部使用,也可以使用`@AutoConfigureTestEntityManager`注释。`JdbcTemplate`如果需要,也可以使用A。以下示例显示了`@DataJpaTest`正在使用的注释:

    import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.orm.jpa.; import static org.assertj.core.api.Assertions.; @DataJpaTest class ExampleRepositoryTests { @Autowired private TestEntityManager entityManager; @Autowired private UserRepository repository; @Test void testExample() throws Exception { this.entityManager.persist(new User(“sboot”, “1234”)); User user = this.repository.findByUsername(“sboot”); assertThat(user.getUsername()).isEqualTo(“sboot”); assertThat(user.getVin()).isEqualTo(“1234”); } }

    1. 内存嵌入式数据库通常运行良好,不需要任何安装,因此通常可以很好地进行测试。但是,如果您希望对真实数据库运行测试,则可以使用`@AutoConfigureTestDatabase`注释,如以下示例所示:

    @DataJpaTest @AutoConfigureTestDatabase(replace=Replace.NONE) class ExampleRepositoryTests { // … }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test"></a>
    2. #### 26.3.17 自动配置的JDBC测试
    3. `@JdbcTest`与相似,`@DataJpaTest`但适用于仅需`DataSource`使用且不使用Spring Data JDBC的测试。默认情况下,它配置一个内存嵌入式数据库和一个`JdbcTemplate`。使用注解时,不会扫描Regular`@Component`和`@ConfigurationProperties`bean `@JdbcTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。
    4. | | 由启用了自动配置的列表`@JdbcTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    5. | :---: | --- |
    6. 缺省情况下,JDBC测试是事务性的,并在每次测试结束时回滚。有关更多详细信息,请参见Spring Framework参考文档中的[相关部分](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#testcontext-tx-enabling-transactions)。如果这不是您想要的,则可以为测试或整个类禁用事务管理,如下所示:

    import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @JdbcTest @Transactional(propagation = Propagation.NOT_SUPPORTED) class ExampleNonTransactionalTests { }

    1. 如果您希望测试针对真实数据库运行,则可以使用`@AutoConfigureTestDatabase`与相同的注释方式`DataJpaTest`。(请参阅“[自动配置的数据JPA测试](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test)”。)
    2. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-data-jdbc-test"></a>
    3. #### 26.3.18 自动配置的数据JDBC测试
    4. `@DataJdbcTest`类似于`@JdbcTest`但适用于使用Spring Data JDBC存储库的测试。默认情况下,它配置一个内存嵌入式数据库,一个`JdbcTemplate`Spring Data JDBC存储库。使用注解时,不会扫描Regular`@Component``@ConfigurationProperties`bean `@DataJdbcTest` `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。
    5. | | 由启用了自动配置的列表`@DataJdbcTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    6. | :---: | --- |
    7. 默认情况下,Data JDBC测试是事务性的,并在每个测试结束时回滚。有关更多详细信息,请参见Spring Framework参考文档中的[相关部分](https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/reference/html/testing.html#testcontext-tx-enabling-transactions)。如果这不是您想要的,则可以禁用测试或整个测试类的事务管理,如[JDBC示例所示](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test)。<br />如果您希望测试针对真实数据库运行,则可以使用`@AutoConfigureTestDatabase`与相同的注释方式`DataJpaTest`。(请参阅“[自动配置的数据JPA测试](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test)”。)
    8. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-jooq-test"></a>
    9. #### 26.3.19 自动配置的jOOQ测试
    10. 您可以使用`@JooqTest``@JdbcTest`jOOQ相关的测试类似的方式进行测试。由于jOOQ严重依赖与数据库模式相对应的基于Java的模式,因此使用现有的模式`DataSource`。如果要用内存数据库替换它,可以使用`@AutoConfigureTestDatabase`覆盖这些设置。(有关将jOOQSpring Boot结合使用的更多信息,请参阅本章前面的“[使用jOOQ](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-jooq) ”。)使用注释时,不会扫描常规`@Component`和`@ConfigurationProperties`bean `@JooqTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。
    11. | | 由启用了自动配置的列表`@JooqTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    12. | :---: | --- |
    13. `@JooqTest`配置一个`DSLContext`。以下示例显示了`@JooqTest`正在使用的注释:

    import org.jooq.DSLContext; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.jooq.JooqTest; @JooqTest class ExampleJooqTests { @Autowired private DSLContext dslContext; }

    1. JOOQ测试是事务性的,默认情况下会在每个测试结束时回滚。如果这不是您想要的,则可以禁用测试或整个测试类的事务管理,如[JDBC示例所示](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test)。
    2. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-mongo-test"></a>
    3. #### 26.3.20 自动配置的数据MongoDB测试
    4. 您可以`@DataMongoTest`用来测试MongoDB应用程序。默认情况下,它配置内存嵌入式MongoDB(如果可用),配置`MongoTemplate`,扫描`@Document`类,并配置Spring Data MongoDB存储库。使用注解时,不会扫描Regular`@Component``@ConfigurationProperties`bean `@DataMongoTest` `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。(有关将MongoDBSpring Boot结合使用的更多信息,请参阅本章前面的“ [MongoDB](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-mongodb) ”。)
    5. | | 的由启用了自动配置设置列表`@DataMongoTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    6. | :---: | --- |
    7. 此类显示`@DataMongoTest`正在使用的注释:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; import org.springframework.data.mongodb.core.MongoTemplate; @DataMongoTest class ExampleDataMongoTests { @Autowired private MongoTemplate mongoTemplate; // }

    1. 内存嵌入式MongoDB通常运行良好,不需要任何开发人员安装,因此通常可以很好地用于测试。但是,如果您希望对真实的MongoDB服务器运行测试,则应排除嵌入式MongoDB自动配置,如以下示例所示:

    import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; @DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class) class ExampleDataMongoNonEmbeddedTests { }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-neo4j-test"></a>
    2. #### 26.3.21 自动配置的数据Neo4j测试
    3. 您可以`@DataNeo4jTest`用来测试Neo4j应用程序。默认情况下,它会扫描`@Node`类,并配置Spring Data Neo4j存储库。使用注解时,不会扫描Regular`@Component`和`@ConfigurationProperties`bean `@DataNeo4jTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。(有关将Neo4J与Spring Boot结合使用的更多信息,请参阅本章前面的“ [Neo4j](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-neo4j) ”。)
    4. | | 的由启用了自动配置设置列表`@DataNeo4jTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    5. | :---: | --- |
    6. 以下示例显示了在Spring Boot中使用Neo4J测试的典型设置:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; @DataNeo4jTest class ExampleDataNeo4jTests { @Autowired private YourRepository repository; // }

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

    import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @DataNeo4jTest @Transactional(propagation = Propagation.NOT_SUPPORTED) class ExampleNonTransactionalTests { }

    1. | | 被动访问不支持事务测试。如果使用此样式,则必须`@DataNeo4jTest`如上所述配置测试。 |
    2. | :---: | --- |
    3. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-redis-test"></a>
    4. #### 26.3.22 自动配置的数据Redis测试
    5. 您可以`@DataRedisTest`用来测试Redis应用程序。默认情况下,它会扫描`@RedisHash`类并配置Spring Data Redis存储库。使用注解时,不会扫描Regular`@Component``@ConfigurationProperties`bean `@DataRedisTest` `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。(有关在Spring Boot中使用Redis的更多信息,请参阅本章前面的“ [Redis](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-redis) ”。)
    6. | | 的由启用了自动配置设置列表`@DataRedisTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    7. | :---: | --- |
    8. 以下示例显示了`@DataRedisTest`正在使用的注释:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest; @DataRedisTest class ExampleDataRedisTests { @Autowired private YourRepository repository; // }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-ldap-test"></a>
    2. #### 26.3.23 自动配置的数据LDAP测试
    3. 您可以`@DataLdapTest`用来测试LDAP应用程序。默认情况下,它配置内存嵌入式LDAP(如果可用),配置`LdapTemplate`,扫描`@Entry`类,并配置Spring Data LDAP存储库。使用注解时,不会扫描Regular`@Component`和`@ConfigurationProperties`bean `@DataLdapTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。(有关将LDAP与Spring Boot结合使用的更多信息,请参阅本章前面的“ [LDAP](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-ldap) ”。)
    4. | | 的由启用了自动配置设置列表`@DataLdapTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    5. | :---: | --- |
    6. 以下示例显示了`@DataLdapTest`正在使用的注释:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest; import org.springframework.ldap.core.LdapTemplate; @DataLdapTest class ExampleDataLdapTests { @Autowired private LdapTemplate ldapTemplate; // }

    1. 内存嵌入式LDAP通常非常适合测试,因为它速度快并且不需要安装任何开发人员。但是,如果您希望对真实的LDAP服务器运行测试,则应排除嵌入式LDAP自动配置,如以下示例所示:

    import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration; import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest; @DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class) class ExampleDataLdapNonEmbeddedTests { }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-client"></a>
    2. #### 26.3.24 自动配置的REST客户端
    3. 您可以使用`@RestClientTest`注释来测试REST客户端。默认情况下,它会自动配置Jackson,GSON和Jsonb支持,配置`RestTemplateBuilder`,并添加对的支持`MockRestServiceServer`。使用注解时,不会扫描Regular`@Component`和`@ConfigurationProperties`bean `@RestClientTest`。 `@EnableConfigurationProperties`可用于包括`@ConfigurationProperties`豆类。
    4. | | 的由启用了自动配置设置列表`@RestClientTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    5. | :---: | --- |
    6. 应该使用的`value`或`components`属性来指定要测试的特定bean `@RestClientTest`,如以下示例所示:

    @RestClientTest(RemoteVehicleDetailsService.class) class ExampleRestClientTest { @Autowired private RemoteVehicleDetailsService service; @Autowired private MockRestServiceServer server; @Test void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() throws Exception { this.server.expect(requestTo(“/greet/details”)) .andRespond(withSuccess(“hello”, MediaType.TEXT_PLAIN)); String greeting = this.service.callRestService(); assertThat(greeting).isEqualTo(“hello”); } }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs"></a>
    2. #### 26.3.25 自动配置的Spring REST Docs测试
    3. 您可以在Mock MVC,REST Assured或WebTestClient的测试中使用`@AutoConfigureRestDocs`批注来使用[Spring REST Docs](https://spring.io/projects/spring-restdocs)。它消除了Spring REST Docs中对JUnit扩展的需求。<br />`@AutoConfigureRestDocs`可以用来覆盖默认的输出目录(`target/generated-snippets`如果您使用的是Maven或`build/generated-snippets`Gradle)。它也可以用于配置出现在任何记录的URI中的主机,方案和端口。
    4. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-mock-mvc"></a>
    5. ##### 使用Mock MVC自动配置的Spring REST Docs测试
    6. `@AutoConfigureRestDocs``MockMvc`在测试基于Servlet的Web应用程序时,将bean定制为使用Spring REST Docs。您可以`@Autowired`像在使用Mock MVC和Spring REST Docs时一样,通过在测试中使用和使用它来注入它,如以下示例所示:

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @WebMvcTest(UserController.class) @AutoConfigureRestDocs class UserDocumentationTests { @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”)); } }

    1. 如果您需要对Spring REST Docs配置进行更多控制,而不是的属性所提供的控制`@AutoConfigureRestDocs`,则可以使用`RestDocsMockMvcConfigurationCustomizer`Bean,如以下示例所示:

    @TestConfiguration static class CustomizationConfiguration implements RestDocsMockMvcConfigurationCustomizer { @Override public void customize(MockMvcRestDocumentationConfigurer configurer) { configurer.snippets().withTemplateFormat(TemplateFormats.markdown()); } }

    1. 如果要使用Spring REST Docs对参数化输出目录的支持,则可以创建一个`RestDocumentationResultHandler`bean`alwaysDo`使用此结果处理程序的自动配置调用,从而导致每个`MockMvc`调用自动生成默认片段。以下示例显示了一个`RestDocumentationResultHandler`正在定义的对象:

    @TestConfiguration(proxyBeanMethods = false) static class ResultHandlerConfiguration { @Bean public RestDocumentationResultHandler restDocumentation() { return MockMvcRestDocumentation.document(“{method-name}”); } }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-web-test-client"></a>
    2. ##### 使用WebTestClient自动配置的Spring REST Docs测试
    3. `@AutoConfigureRestDocs`也可以`WebTestClient`在测试反应式Web应用程序时使用。您可以`@Autowired`像在使用`@WebFluxTest`Spring REST Docs时一样,通过在测试中使用和注入它来进行注入,如以下示例所示:

    import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; import org.springframework.test.web.reactive.server.WebTestClient; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document; @WebFluxTest @AutoConfigureRestDocs class UsersDocumentationTests { @Autowired private WebTestClient webTestClient; @Test void listUsers() { this.webTestClient.get().uri(“/“).exchange().expectStatus().isOk().expectBody() .consumeWith(document(“list-users”)); } }

    1. 如果您需要对Spring REST Docs配置进行更多控制,而不是的属性所提供的控制`@AutoConfigureRestDocs`,则可以使用`RestDocsWebTestClientConfigurationCustomizer`Bean,如以下示例所示:

    @TestConfiguration(proxyBeanMethods = false) public static class CustomizationConfiguration implements RestDocsWebTestClientConfigurationCustomizer { @Override public void customize(WebTestClientRestDocumentationConfigurer configurer) { configurer.snippets().withEncoding(“UTF-8”); } }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-rest-assured"></a>
    2. ##### 具有REST保证的自动配置的Spring REST Docs测试
    3. `@AutoConfigureRestDocs`使`RequestSpecification`预配置为使用Spring REST Docs的bean可用于您的测试。您可以`@Autowired`像在使用REST Assured和Spring REST Docs时一样,通过在测试中使用和使用它来注入它,如以下示例所示:

    import io.restassured.specification.RequestSpecification; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.web.server.LocalServerPort; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.is; import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @AutoConfigureRestDocs class UserDocumentationTests { @Test void listUsers(@Autowired RequestSpecification documentationSpec, @LocalServerPort int port) { given(documentationSpec).filter(document(“list-users”)).when().port(port).get(“/“).then().assertThat() .statusCode(is(200)); } }

    1. 如果需要对Spring REST Docs配置进行更多控制,而不需要通过的属性提供更多控制`@AutoConfigureRestDocs``RestDocsRestAssuredConfigurationCustomizer`则可以使用Bean,如以下示例所示:

    @TestConfiguration(proxyBeanMethods = false) public static class CustomizationConfiguration implements RestDocsRestAssuredConfigurationCustomizer { @Override public void customize(RestAssuredRestDocumentationConfigurer configurer) { configurer.snippets().withTemplateFormat(TemplateFormats.markdown()); } }

    1. <a name="boot-features-testing-spring-boot-applications-testing-autoconfigured-webservices"></a>
    2. #### 26.3.26 自动配置的Spring Web Services测试
    3. 您可以使用`@WebServiceClientTest`Spring Web Services项目来测试使用呼叫Web服务的应用程序。默认情况下,它配置一个模拟`WebServiceServer`bean并自动自定义您的`WebServiceTemplateBuilder`。(有关在Spring Boot中结合使用Web服务的更多信息,请参阅本章前面的“ [Web服务](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-webservices)”。)
    4. | | 的由启用了自动配置设置列表`@WebServiceClientTest`可以[在附录中找到](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/appendix-test-auto-configuration.html#test-auto-configuration)。 |
    5. | :---: | --- |
    6. 以下示例显示了`@WebServiceClientTest`正在使用的注释:

    @WebServiceClientTest(ExampleWebServiceClient.class) class WebServiceClientIntegrationTests { @Autowired private MockWebServiceServer server; @Autowired private ExampleWebServiceClient client; @Test void mockServerCall() { this.server.expect(payload(new StringSource(““))).andRespond( withPayload(new StringSource(“200“))); assertThat(this.client.test()).extracting(Response::getStatus).isEqualTo(200); } }

    1. <a name="boot-features-testing-spring-boot-applications-testing-auto-configured-additional-auto-config"></a>
    2. #### 26.3.27 额外的自动配置和切片
    3. 每个切片提供一个或多个`@AutoConfigure…`注释,这些注释即定义应包含在切片中的自动配置。可以通过创建自定义`@AutoConfigure…`批注或添加`@ImportAutoConfiguration`到测试中来逐个测试添加其他自动配置,如以下示例所示:

    @JdbcTest @ImportAutoConfiguration(IntegrationAutoConfiguration.class) class ExampleJdbcTests { }

    1. | | 确保不要使用常规`@Import`注释来导入自动配置,因为它们是由Spring Boot以特定方式处理的。 |
    2. | :---: | --- |
    3. 或者,可以通过`META-INF/spring.factories`以下示例中所示的注册方式为切片注释的任何使用添加其他自动配置:<br />org.springframework.boot.test.autoconfigure.jdbc.JdbcTest = com.example.IntegrationAutoConfiguration
    4. | | 只要切片或`@AutoConfigure…`注释使用meta注释,就可以通过这种方式进行自定义`@ImportAutoConfiguration` |
    5. | :---: | --- |
    6. <a name="boot-features-testing-spring-boot-applications-testing-user-configuration"></a>
    7. #### 26.3.28 用户配置和切片
    8. 如果您以合理的方式[构建代码](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/using-spring-boot.html#using-boot-structuring-your-code),`@SpringBootApplication`则[默认情况下](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-detecting-config)会将您的类[用作](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-detecting-config)测试的配置。<br />因此,重要的是不要用特定于应用程序功能特定区域的配置设置来乱扔应用程序的主类。<br />假设您正在使用Spring Batch,并且依赖于它的自动配置。您可以定义`@SpringBootApplication`如下:

    @SpringBootApplication @EnableBatchProcessing public class SampleApplication { … }

    1. 因为此类是测试的源配置,所以任何切片测试实际上都尝试启动Spring Batch,这绝对不是您想要执行的操作。建议的方法是将特定于区域的配置移到`@Configuration`与您的应用程序相同级别的单独的类,如以下示例所示:

    @Configuration(proxyBeanMethods = false) @EnableBatchProcessing public class BatchConfiguration { … }

    1. | | 根据您应用程序的复杂性,您可以`@Configuration`为您的自定义设置一个类,也可以为每个域区域指定一个类。使用后一种方法,您可以在其中的一个测试中启用`@Import`注释(如有必要),并带有注释。 |
    2. | :---: | --- |
    3. 测试切片将`@Configuration`类别排除在扫描范围之外。例如,对于a `@WebMvcTest`,以下配置将`WebMvcConfigurer`在测试切片加载的应用程序上下文中不包括给定的bean

    @Configuration public class WebConfiguration { @Bean public WebMvcConfigurer testConfigurer() { return new WebMvcConfigurer() { … }; } }

    1. 但是,以下配置将导致自定义`WebMvcConfigurer`由测试片加载。

    @Component public class TestWebMvcConfigurer implements WebMvcConfigurer { … }

    1. 混乱的另一个来源是类路径扫描。假设在以合理的方式组织代码的同时,您需要扫描其他程序包。您的应用程序可能类似于以下代码:

    @SpringBootApplication @ComponentScan({ “com.example.app”, “org.acme.another” }) public class SampleApplication { … }

    1. 这样做有效地覆盖了默认的组件扫描指令,并且具有扫描这两个软件包的副作用,而与您选择的切片无关。例如,`@DataJpaTest`似乎突然扫描了应用程序的组件和用户配置。同样,将自定义指令移至单独的类是解决此问题的好方法。
    2. | | 如果这不是您的选择,则可以`@SpringBootConfiguration`在测试层次结构中的某个位置创建一个位置,以便代替使用它。另外,您可以为测试指定一个源,从而禁用查找默认源的行为。 |
    3. | :---: | --- |
    4. <a name="boot-features-testing-spring-boot-applications-with-spock"></a>
    5. #### 26.3.29 使用Spock测试Spring Boot应用程序
    6. 如果您希望使用Spock测试Spring Boot应用程序,则应在`spock-spring`应用程序的构建中添加对Spock模块的依赖。 `spock-spring`Spring的测试框架集成到Spock中。建议您使用Spock 1.2或更高版本,以受益于SpockSpring框架和Spring Boot集成的许多改进。有关更多详细信息,请参见[SpockSpring模块的文档](http://spockframework.org/spock/docs/1.2/modules.html#_spring_module)。
    7. <a name="boot-features-test-utilities"></a>
    8. ### 26.4 测试工具
    9. 在测试应用程序时通常会有用的一些测试实用程序类作为打包在一起`spring-boot`
    10. <a name="boot-features-configfileapplicationcontextinitializer-test-utility"></a>
    11. #### 26.4.1 ConfigFileApplicationContextInitializer
    12. `ConfigFileApplicationContextInitializer`是一个`ApplicationContextInitializer`可以应用于测试以加载Spring Boot`application.properties`文件的工具。如不需要`@SpringBootTest`以下示例所示,可以在不需要由提供的全部功能时使用它:

    @ContextConfiguration(classes = Config.class, initializers = ConfigFileApplicationContextInitializer.class)

    1. | | `ConfigFileApplicationContextInitializer`单独 使用不能为`@Value("${…}")`注射提供支持。唯一的工作是确保将`application.properties`文件加载到Spring的中`Environment`。为了获得`@Value`支持,您需要另外配置a`PropertySourcesPlaceholderConfigurer`或使用`@SpringBootTest`,后者会为您自动配置一个。 |
    2. | :---: | --- |
    3. <a name="boot-features-test-property-values"></a>
    4. #### 26.4.2 TestPropertyValues
    5. `TestPropertyValues`可让您快速将属性添加到`ConfigurableEnvironment``ConfigurableApplicationContext`。您可以使用`key=value`字符串来调用它,如下所示:

    TestPropertyValues.of(“org=Spring”, “name=Boot”).applyTo(env);

    1. <a name="boot-features-output-capture-test-utility"></a>
    2. #### 26.4.3 OutputCapture
    3. `OutputCapture`是一个JUnit `Extension`,可用于捕获`System.out`和`System.err`输出。要使用add`@ExtendWith(OutputCaptureExtension.class)`和ject`CapturedOutput`作为测试类构造函数或测试方法的参数,如下所示:

    @ExtendWith(OutputCaptureExtension.class) class OutputCaptureTests { @Test void testName(CapturedOutput output) { System.out.println(“Hello World!”); assertThat(output).contains(“World”); } }

    1. <a name="boot-features-rest-templates-test-utility"></a>
    2. #### 26.4.4 TestRestTemplate
    3. `TestRestTemplate`是Spring的一种方便替代方法,`RestTemplate`在集成测试中很有用。您可以使用普通模板或发送基本HTTP身份验证(带有用户名和密码)的模板。在这两种情况下,模板都不会通过在服务器端错误上引发异常来以易于测试的方式运行。
    4. | | Spring Framework 5.0提供了一个新功能`WebTestClient`,可用于[WebFlux集成测试](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-webflux-tests)以及[WebFlux和MVC端到端测试](https://docs.spring.io/spring-boot/docs/2.4.0-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications-testing-with-running-server)。与相比,它为声明提供了流畅的API `TestRestTemplate`。 |
    5. | :---: | --- |
    6. 建议(但不是强制性的)使用Apache HTTP Client(版本4.3.2或更高版本)。如果您在类路径中具有该名称,则`TestRestTemplate`通过适当配置客户端来做出响应。如果确实使用Apache的HTTP客户端,则会启用一些其他易于测试的功能:
    7. - 不遵循重定向(因此您可以声明响应位置)。
    8. - Cookies被忽略(因此模板是无状态的)。
    9. `TestRestTemplate` 可以在集成测试中直接实例化,如以下示例所示:

    public class MyTest { private TestRestTemplate template = new TestRestTemplate(); @Test public void testRequest() throws Exception { HttpHeaders headers = this.template.getForEntity( “https://myhost.example.com/example“, String.class).getHeaders(); assertThat(headers.getLocation()).hasHost(“other.example.com”); } }

    1. 另外,如果将`@SpringBootTest`注释与`WebEnvironment.RANDOM_PORT`或结合使用,则`WebEnvironment.DEFINED_PORT`可以注入完全配置的注释`TestRestTemplate`并开始使用它。如有必要,可以通过`RestTemplateBuilder`Bean应用其他定制。未指定主机和端口的所有URL都会自动连接到嵌入式服务器,如以下示例所示:

    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class SampleWebClientTests { @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 Config { @Bean RestTemplateBuilder restTemplateBuilder() { return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1)) .setReadTimeout(Duration.ofSeconds(1)); } } } ```