Testing
Spring Boot 提供了许多实用工具和注释,以帮助测试你的应用程序.测试支持由两个模块提供: spring-boot-test 包含核心项目,而 spring-boot-test-autoconfigure 支持自动配置测试.
大多数开发人员使用 spring-boot-starter-test “Starter”,它导入 Spring Boot 的两项测试模块以及 JUnit Jupiter、AssertJ、Hamcrest 以及许多其他有用的库.
|
如果你具有使用 JUnit 4 的测试,则可以使用 JUnit 5 的 vintage 引擎来运行它们.若要使用 vintage 引擎,请添加对
|
hamcrest-core`被排除在外,优先使用 `org.hamcrest:hamcrest,后者是 `spring-boot-starter-test`的一部分。
Test Scope Dependencies
spring-boot-starter-test “Starter”(在 test `scope`中)包含以下提供的库:
-
JUnit 5:用于测试 Java 应用程序的事实标准。
-
{url-spring-framework-docs}/testing/integration.html[Spring Test] 和 Spring Boot Test:Spring Boot 应用程序的实用工具和集成测试支持。
-
AssertJ:一个流畅的断言库。
-
Hamcrest:一个匹配器对象库(也称为约束或谓词)。
-
Mockito:一个 Java 模拟框架。
-
JSONassert:一个用于 JSON 的断言库。
-
JsonPath: XPath for JSON.
-
Awaitility:一个用于测试异步系统的库。
我们通常会发现这些常见的库在写测试时很有用。如果这些库不适合您的需要,则可以添加您自己的额外的测试依赖项。
Testing Spring Applications
依赖注入的一大优点在于它应该让您的代码更容易进行单元测试。您可以使用 `new`运算符实例化对象,而无需 Spring 参与。您还可以使用 _mock objects_代替实际依赖项。
通常,您需要超越单元测试,并开始集成测试(使用 Spring ApplicationContext)。能够在不需要部署您的应用程序或不需要连接到其他基础设施的情况下执行集成测试非常有用。
Spring 框架包含一个专门用于此类集成测试的测试模块。您可以直接对 org.springframework:spring-test`声明一个依赖项,或使用 `spring-boot-starter-test "`Starter`"以传递方式引入它。
如果您之前没有使用过 `spring-test`模块,您应该首先阅读 Spring 框架参考文档中{url-spring-framework-docs}/testing.html[相关部分]。
Testing Spring Boot Applications
Spring Boot 应用程序是一个 Spring ApplicationContext,因此除了针对普通 Spring 上下文通常要做的工作之外,测试它不需要做任何特别的事情。
|
Spring Boot 的外部属性、日志记录和其他功能只有在您使用 `SpringApplication`创建上下文时才会默认安装到上下文中。 |
Spring Boot 提供一个 @SpringBootTest`注释,当您需要 Spring Boot 功能时,它可以用作标准 `spring-test @ContextConfiguration`注释的替代项。注释通过 creating the `ApplicationContext used in your tests through SpringApplication起作用。除了 `@SpringBootTest`之外,还提供了一些其他注释以 testing more specific slices应用程序。
|
如果您使用的是 JUnit 4,请不要忘记还将 |
默认情况下,`@SpringBootTest`不会启动服务器。您可以使用 `@SpringBootTest`的 `webEnvironment`属性以进一步细化测试的运行方式:
-
MOCK(默认):加载 Web 应用程序上下文并提供一个模拟的 Web 环境。使用此注释时不会启动嵌入式服务器。如果类路径上没有 Web 环境,则此模式会透明地回退为创建常规的、非 WebApplicationContext。它可以与@AutoConfigureMockMvcor@AutoConfigureWebTestClient结合使用,以对您的 Web 应用程序进行基于模拟的测试。 -
RANDOM_PORT:加载 Web 应用程序上下文并提供一个真正的 Web 环境。启动嵌入式服务器并侦听一个随机端口。 -
DEFINED_PORT:加载 Web 应用程序上下文并提供一个真正的 Web 环境。启动嵌入式服务器并侦听一个已定义的端口(来自您的application.properties)或 `8080`的默认端口。 -
NONE:使用 `SpringApplication`加载 Web 应用程序上下文,但不提供 _any_Web 环境(模拟或其他)。
|
如果您的测试是 |
|
`@SpringBootTest`与 `webEnvironment = WebEnvironment.RANDOM_PORT`还将在一个单独的随机端口上启动管理服务器,如果您的应用程序针对管理服务器使用某个不同的端口。 |
Detecting Web Application Type
如果提供了 Spring MVC,则会配置基于常规 MVC 的应用程序上下文。如果您只有 Spring WebFlux,则我们会检测到这一点并改为配置基于 WebFlux 的应用程序上下文。
如果两个都存在,则 Spring MVC 优先。如果您希望在此场景中测试响应式 Web 应用程序,则必须设置 configprop:spring.main.web-application-type[] 属性:
Detecting Test Configuration
如果您熟悉 Spring 测试框架,则可能习惯使用 `@ContextConfiguration(classes=…)`以指定要加载哪个 Spring 应用程序上下文。此外,您可能经常在测试中使用嵌套的 `@Configuration`类。
在测试 Spring Boot 应用程序时,通常不需要这样做。Spring Boot 的 `@*Test`注释会在您没有明确定义一个注释时自动搜索您的主配置。
搜索算法从包含测试的包开始,一直往上查找,直到找到使用 `@SpringBootApplication`或 `@SpringBootConfiguration`进行注释的类。只要您以合理的方式进行 structured your code,通常能够找到您的主配置。
|
如果您使用了 test annotation to test a more specific slice of your application,则应该避免向 main method’s application class上特定区域添加配置设置。 `@SpringBootApplication`的底层组件扫描配置定义了排除过滤器,这些过滤器用于确保分片工作按预期进行。如果您在 `@SpringBootApplication`注释类上使用明确的 `@ComponentScan`指令,请注意这些过滤器将被禁用。如果您正在使用分片,则应重新定义它们。 |
如果您想要自定义主配置,可以使用一个嵌套 `@TestConfiguration`类。与将用作应用程序主配置的嵌套 `@Configuration`类不同,嵌套的 `@TestConfiguration`类是作为应用程序主配置的补充使用的。
|
Spring 的测试框架会缓存测试之间的应用程序上下文。因此,只要您的测试共享相同的配置(无论如何发现的),加载上下文的耗时过程只发生一次。 |
Using the Test Configuration Main Method
通常,@SpringBootTest`发现的测试配置将是您的主 `@SpringBootApplication。在大多数结构良好的应用程序中,此配置类还将包含用于启动应用程序的 `main`方法。
例如,以下代码模式对于典型的 Spring Boot 应用程序来说非常常见:
在上述示例中,main 方法除了委托给 SpringApplication.run 之外,不会执行任何其他操作.但是,在调用 SpringApplication.run 之前,可以通过更复杂的 main 方法来应用自定义设置.
例如,以下是一个更改横幅模式并设置其他配置文件的应用程序:
由于 main 方法中的自定义会影响由此产生的 ApplicationContext,所以您可能还想使用 main 方法来创建测试中使用的 ApplicationContext。默认情况下,@SpringBootTest 不会调用您的 main 方法,而是直接使用类本身来创建 ApplicationContext
如果您想更改此行为,可以将 @SpringBootTest 的 useMainMethod 属性更改为 UseMainMethod.ALWAYS 或 UseMainMethod.WHEN_AVAILABLE。如果将其设置为 ALWAYS,并且无法找到 main 方法,则测试将失败。如果将其设置为 WHEN_AVAILABLE,如果存在 main 方法,它将被使用;否则,将使用标准加载机制。
例如,以下测试将调用 MyApplication 的 main 方法以创建 ApplicationContext。如果主方法设置另外的配置文件,则当 ApplicationContext 启动时它们将处于活动状态。
Excluding Test Configuration
如果你的应用程序使用组件扫描(例如,如果你使用 @SpringBootApplication 或 @ComponentScan),你可能会发现自己只为特定测试创建的顶级配置类意外地被到处选取。
正如我们have seen earlier,@TestConfiguration 可以用于测试的内部类以自定义主配置。@TestConfiguration 也可以用于顶级类。这样表示该类不应通过扫描选取。然后,你可以在需要的地方显式导入该类,如下面的示例中所示:
|
如果你直接使用 |
|
已导入的 |
Using Application Arguments
如果您的应用程序期望 arguments,您可以使用 args 属性让 @SpringBootTest 注入它们。
Testing With a Mock Environment
默认情况下,@SpringBootTest 不会启动服务器,而是为测试 Web 端点设置模拟环境。
使用 Spring MVC,我们可以使用 {url-spring-framework-docs}/testing/spring-mvc-test-framework.html[MockMvc] 或 WebTestClient 查询我们的 Web 端点,如下例所示:
|
如果您只想关注 Web 层而不想启动一个完整的 |
使用 Spring WebFlux 端点,您可以使用 {url-spring-framework-docs}/testing/webtestclient.html[WebTestClient],如下例所示:
包括代码:MyMockWebTestClientTests[]
|
在模拟环境里进行测试通常比使用完整的 Servlet 容器运行测试更快。但是,由于模拟发生在 Spring MVC 层,因此依赖于较低级别 Servlet 容器行为的代码无法使用 MockMvc 直接进行测试。 例如,Spring Boot 的错误处理基于 servlet 容器提供的 “error page” 支持。这意味着,虽然可以测试 MVC 层按预期抛出和处理异常,但无法直接测试是否渲染了特定的 custom error page。如果需要测试这些低层级问题,可以按照下一部分中所述启动一个完全运行的服务器。 |
Testing With a Running Server
如果需要启动一个完全运行的服务器,建议使用随机端口。如果使用 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT),那么在每次运行测试时都会随机选择一个可用端口。
可以 inject the actual port used 到测试中,以使用 @LocalServerPort 批注。为了方便,需要对已启动的服务器进行 REST 调用的测试还可以 @Autowire 一个 {url-spring-framework-docs}/testing/webtestclient.html[WebTestClient],该注解解析到正在运行的服务器的相对链接,并提供了一个专门的 API 用于验证响应,如下例所示:
在测试中使用 inject the actual port used 代码:MyRandomPortWebTestClientTests[]
|
|
此设置需要 spring-webflux 位于类路径上。如果无法或不愿添加 WebFlux,Spring Boot 还提供了一个 TestRestTemplate 工具:
在测试中使用 TestRestTemplate 代码:MyRandomPortTestRestTemplateTests[]
Customizing WebTestClient
若要自定义 WebTestClient bean,请配置 WebTestClientBuilderCustomizer bean。此类任何 bean 都使用用于创建 WebTestClient 的 WebTestClient.Builder 进行调用。
Using JMX
由于测试上下文框架会缓存上下文,所以 JMX 默认被禁用,以防止相同组件注册在同一域上。如果此类测试需要访问 MBeanServer,请考虑也将其标记为脏:
在测试中使用 MBeanServer 代码:MyJmxTests[]
Using Observations
如果为 a sliced test 添加 @AutoConfigureObservability 批注,它将自动配置一个 ObservationRegistry。
Using Metrics
无论类路径是什么,使用 @SpringBootTest 时,仪表注册表(除了内存后备)都不会自动配置。
如果需要在集成测试中将指标导出到不同后端,请对其添加 @AutoConfigureObservability 批注。
如果为 a sliced test 添加 @AutoConfigureObservability 批注,它会自动配置一个内存 MeterRegistry。在分块测试中使用 @AutoConfigureObservability 批注进行数据导出不受支持。
Using Tracing
无论您的类路径如何,在使用 `@SpringBootTest`时,报告数据的跟踪组件均不会自动配置。
如果您需要那些组件作为集成测试的一部分,请使用 @AutoConfigureObservability 注释该测试。
如果您已创建了自定义报告组件(例如自定义 SpanExporter 或 SpanHandler),并且您不希望它们在测试中处于活动状态,则可以使用 @ConditionalOnEnabledTracing 注释禁用它们。
如果您使用 @AutoConfigureObservability 注释 a sliced test ,它将自动配置无操作 Tracer 。使用 @AutoConfigureObservability 注释,在切片测试中不支持数据导出。
Mocking and Spying Beans
在运行测试时,有时需要模拟应用程序上下文中特定组件。例如,在开发过程中可能无法使用某个远程服务的模式。当您想要模拟在真实的环境中可能难以触发的故障时,模拟也可能非常有用。
Spring Boot 包含 @MockBean 注释,该注释可用于为 ApplicationContext 内的 Bean 定义一个 Mockito 模拟。可以使用此注释添加新 Bean 或替换现有的单一 Bean 定义。此注释可直接用于测试类、测试中的字段或 @Configuration 类和字段。当用在字段上时,也会注入创建的模拟实例。模拟 Bean 会在每次测试方法后自动重置。
|
如果您的测试使用 Spring Boot 的任何测试注释(例如 |
以下示例使用模拟实现替换现有 RemoteService Bean:
|
|
此外,您还可以使用 @SpyBean 包装任何现有 Bean 使用 Mockito spy 。有关详细信息,请参阅 Javadoc 。
|
虽然 Spring 的测试框架在测试之间缓存应用程序上下文并为共享相同配置的测试重新使用一个上下文,但使用 |
|
如果您正在使用 |
|
当您使用 |
Auto-configured Tests
Spring Boot 的自动配置系统适用于应用程序,但有时对于测试来说可能会有点过分。它通常有助于仅加载测试应用程序的 “slice” 所需的配置部分。例如,您可能希望测试 Spring MVC 控制器是否正确映射了 URL,并且您不希望在这些测试中涉及数据库调用,或者您可能希望测试 JPA 实体,并且您在这些测试运行时不关心 Web 层。
spring-boot-test-autoconfigure 模块包含许多注释,可用于自动配置此类 “slices” 。它们每个的工作方式类似,提供加载 ApplicationContext 和一个或多个可用于自定义自动配置设置的 @AutoConfigure… 注释的 @…Test 注释。
|
每个切片将组件扫描限制为适当的组件,并加载非常有限的一组自动配置类。如果您需要排除其中之一,大多数 |
|
在一个测试中使用多个 “slices” 时,不支持使用多个 |
|
还可以将 |
Auto-configured JSON Tests
使用 @JsonTest 注解测试对象 JSON 序列化和反序列化的工作是否符合预期。@JsonTest 自动配置可用的受支持 JSON 映射器,映射器可能是以下某个库:
-
Jackson
ObjectMapper、任何@JsonComponentbean 和任何 JacksonModule -
Gson -
Jsonb
|
由 |
如果您需要配置自动配置的元素,可以使用 @AutoConfigureJsonTesters 注解。
Spring Boot 包含基于 AssertJ 的帮助器,可与 JSONAssert 和 JsonPath 库配合使用,以检查 JSON 是否符合预期。JacksonTester、GsonTester、JsonbTester 和 BasicJsonTester 类分别可用于 Jackson、Gson、Jsonb 和字符串。在使用 @JsonTest 时,测试类上的任何帮助器字段均可 @Autowired。以下示例显示 Jackson 的测试类:
|
JSON 帮助器类还可以在标准单元测试中直接使用。若要执行此操作,请在 |
如果您使用 Spring Boot 基于 AssertJ 的帮助器来断言给定 JSON 路径处的数值,则可能无法根据类型使用 isEqualTo。相反,您可以使用 AssertJ 的 satisfies 来断言该值符合给定的条件。例如,以下示例断言实际数字是一个浮点值,接近 0.15,偏移量在 0.01 之内。
Auto-configured Spring MVC Tests
要测试 Spring MVC 控制器是否符合预期,请使用 @WebMvcTest 注解。@WebMvcTest 自动配置 Spring MVC 基础架构,并使扫描的 bean 仅限于 @Controller、@ControllerAdvice、@JsonComponent、Converter、GenericConverter、Filter、HandlerInterceptor、WebMvcConfigurer、WebMvcRegistrations 和 HandlerMethodArgumentResolver。使用 @WebMvcTest 注解时,不会扫描常规 @Component 和 @ConfigurationProperties bean。可以使用 @EnableConfigurationProperties 来包含 @ConfigurationProperties bean。
|
可以 found in the appendix 启用 |
|
如果您需要注册其他组件,如 Jackson |
通常,@WebMvcTest 被限制到单个控制器,并与 @MockBean 结合使用,以便为必需的协作者提供模拟实现。
@WebMvcTest 还自动配置 MockMvc。模拟 MVC 提供了一种快速测试 MVC 控制器的方法,而无需启动一个完整的 HTTP 服务器。
|
您还可以在非 |
|
如果您需要配置自动配置的元素(例如,应应用哪些 servlet 过滤器),则可以在 |
如果您使用 HtmlUnit 和 Selenium,自动配置还提供了一个 HtmlUnit WebClient bean 和/或一个 Selenium WebDriver bean。以下示例使用 HtmlUnit:
包含代码:MyHtmlUnitTests[]
|
默认情况下,Spring Boot 将 |
Spring Boot 创建的 webDriver 作用域将替换同名的任何用户定义作用域。如果您定义自己的 webDriver 作用域,可能会发现当使用 @WebMvcTest 时它停止工作。
如果类路径上有 Spring Security,@WebMvcTest 也将扫描 WebSecurityConfigurer bean。您可以使用 Spring Security 的测试支持,而不用为此类测试完全禁用安全。有关如何使用 Spring Security 的 MockMvc 支持的更多详细内容,请参阅此 Testing With Spring Security 指南部分。
|
有时编写 Spring MVC 测试还不够;Spring Boot 可以帮助您运行 full end-to-end tests with an actual server。 |
Auto-configured Spring WebFlux Tests
要测试 {url-spring-framework-docs}/web-reactive.html[Spring WebFlux] 控制器是否按预期工作,可以使用 @WebFluxTest 注解。@WebFluxTest 自动配置 Spring WebFlux 基础设施,并将扫描的 bean 限制为 @Controller、@ControllerAdvice、@JsonComponent、Converter、GenericConverter、WebFilter 和 WebFluxConfigurer。使用 @WebFluxTest 注解时,不会扫描常规 @Component 和 @ConfigurationProperties bean。可以用 @EnableConfigurationProperties 包括 @ConfigurationProperties bean。
|
可以通过 found in the appendix获取 |
|
如果您需要注册额外的组件,如 Jackson |
通常,@WebFluxTest 局限于单个控制器,并与 @MockBean 注解结合使用,为所需的协作者提供模拟实现。
@WebFluxTest 还自动配置了 {url-spring-framework-docs}/testing/webtestclient.html[WebTestClient],它提供了一种强大的方式来快速测试 WebFlux 控制器,而无需启动完整的 HTTP 服务器。
|
您还可以在非 |
|
此设置仅受 WebFlux 应用程序支持,因为在模拟 Web 应用程序中使用 |
|
|
|
|
|
有时编写 Spring WebFlux 测试还不够;Spring Boot 可以帮助您运行 full end-to-end tests with an actual server。 |
Auto-configured Spring GraphQL Tests
Spring GraphQL 提供了一个专门的测试支持模块;您需要将其添加到项目中:
<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>
dependencies {
testImplementation("org.springframework.graphql:spring-graphql-test")
// Unless already present in the implementation configuration
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
}
此测试模块发送 {url-spring-graphql-docs}/#testing-graphqltester[GraphQlTester]。测试仪在测试中得到了广泛使用,因此务必熟悉它的使用。有 GraphQlTester 变体,Spring Boot 会根据测试类型自动配置它们:
-
ExecutionGraphQlServiceTester在服务器端执行测试,没有客户端或传输 -
HttpGraphQlTester执行带有对服务器的连接的客户端(可能存在或不存在一个实时服务器)的测试
Spring Boot 可帮助您使用 @GraphQlTest 注释测试 {url-spring-graphql-docs}/#controllers[Spring GraphQL 控制器]。@GraphQlTest 自动配置 Spring GraphQL 基础架构,而不涉及任何传输或服务器。这将扫描的 bean 限制为 @Controller、RuntimeWiringConfigurer、JsonComponent、Converter、GenericConverter、DataFetcherExceptionResolver、Instrumentation 和 GraphQlSourceBuilderCustomizer。使用 @GraphQlTest 注释时,不会扫描常规 @Component 和 @ConfigurationProperties bean。@EnableConfigurationProperties 用于包含 @ConfigurationProperties bean。
|
完整的自动配置列表可以通过 |
通常,@GraphQlTest 仅限于一组控制器,并与 @MockBean 注释结合使用,以便为所需的协作者提供模拟实现。
::include-code::GreetingControllerTests[]
@SpringBootTest 测试是完全集成测试,涉及整个应用程序。在使用随机或定义的端口时,将会配置一个实时服务器,并且将自动提供 HttpGraphQlTester bean,以便您可以使用它来测试服务器。在配置了 MOCK 环境时,您还可以通过使用 @AutoConfigureHttpGraphQlTester 标注测试类,来请求 HttpGraphQlTester bean:
::include-code::GraphQlIntegrationTests[]
Auto-configured Data Cassandra Tests
您可以使用 @DataCassandraTest 来测试 Cassandra 应用程序。默认情况下,它会配置 CassandraTemplate、扫描 @Table 类,并配置 Spring Data Cassandra 存储库。使用 @DataCassandraTest 注释时,不会扫描常规 @Component 和 @ConfigurationProperties bean。@EnableConfigurationProperties 用于包含 @ConfigurationProperties bean。(有关如何将 Cassandra 与 Spring Boot 搭配使用的更多信息,请参见 "Cassandra"。)
|
完整的自动配置设置列表可以通过 |
以下示例显示了在 Spring Boot 中使用 Cassandra 测试的典型设置:
::include-code::MyDataCassandraTests[]
Auto-configured Data Couchbase Tests
您可以使用 @DataCouchbaseTest 来测试 Couchbase 应用程序。默认情况下,它会配置 CouchbaseTemplate 或 ReactiveCouchbaseTemplate、扫描 @Document 类,并配置 Spring Data Couchbase 存储库。使用 @DataCouchbaseTest 注释时,不会扫描常规 @Component 和 @ConfigurationProperties bean。@EnableConfigurationProperties 用于包含 @ConfigurationProperties bean。(有关如何将 Couchbase 与 Spring Boot 搭配使用的更多信息,请参见本章前面的 "Couchbase"。)
|
完整的自动配置设置列表可以通过 |
以下示例显示了在 Spring Boot 中使用 Couchbase 测试的典型设置:
::include-code::MyDataCouchbaseTests[]
Auto-configured Data Elasticsearch Tests
您可以使用 @DataElasticsearchTest 来测试 Elasticsearch 应用程序。默认情况下,它会配置 ElasticsearchRestTemplate、扫描 @Document 类,并配置 Spring Data Elasticsearch 存储库。使用 @DataElasticsearchTest 注释时,不会扫描常规 @Component 和 @ConfigurationProperties bean。@EnableConfigurationProperties 用于包含 @ConfigurationProperties bean。(有关如何将 Elasticsearch 与 Spring Boot 搭配使用的更多信息,请参见本章前面的 "Elasticsearch"。)
|
完整的自动配置设置列表可以通过 |
以下示例显示了在 Spring Boot 中使用 Elasticsearch 测试的典型设置:
::include-code::MyDataElasticsearchTests[]
Auto-configured Data JPA Tests
您可以使用`@DataJpaTest`注释来测试JPA应用程序。默认情况下,它扫描`@Entity`类和配置Spring Data JPA存储库。如果类路径中存在嵌入式数据库,它也会配置一个。通过将`spring.jpa.show-sql`属性设置为`true`,默认情况下会记录SQL查询。这可以使用注释的`showSql`属性禁用。
使用`@DataJpaTest`注释时,不会扫描常规`@Component`和`@ConfigurationProperties`bean。@EnableConfigurationProperties`可用于包含@ConfigurationProperties`bean。
|
由`@DataJpaTest`启用的自动配置设置的列表可以found in the appendix。 |
默认情况下,data JPA测试是事务性的,并在每个测试结束时回滚。有关更多详细信息,请参阅Spring Framework参考文档中的{url-spring-framework-docs}/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions[相关章节]。如果不是您想要的内容,您可以按以下方式禁用测试或整个类的交易管理:
数据JPA测试也可能注入 {code-spring-boot-test-autoconfigure-src}/orm/jpa/TestEntityManager.java[TestEntityManager] bean,它提供了专为测试而设计的标准JPA`EntityManager`的替代方案。
|
还可以通过添加`@AutoConfigureTestEntityManager`将`TestEntityManager`自动配置到任何基于Spring的测试类。这样做时,请确保您的测试正在事务中运行,例如通过在您的测试类或方法上添加`@Transactional`。 |
如果需要,还提供了一个`JdbcTemplate`。以下示例显示了正在使用的`@DataJpaTest`注释:
基于内存的嵌入式数据库通常适用于测试,因为它们速度快且无需安装。但是,如果您更愿意针对实际数据库运行测试,则可以使用`@AutoConfigureTestDatabase`注释,如以下示例所示:
Auto-configured JDBC Tests
@JdbcTest`类似于@DataJpaTest`,但适用于仅需要`DataSource`的测试并且不使用Spring Data JDBC。默认情况下,它配置了一个内存中的嵌入式数据库和一个`JdbcTemplate`。使用`@JdbcTest`注释时,不会扫描常规`@Component`和`@ConfigurationProperties`bean。@EnableConfigurationProperties`可用于包含@ConfigurationProperties`bean。
|
由`@JdbcTest`启用的自动配置的列表可以found in the appendix。 |
默认情况下,JDBC测试是事务性的,并在每个测试结束时回滚。有关更多详细信息,请参阅Spring Framework参考文档中的{url-spring-framework-docs}/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions[相关章节]。如果不是您想要的内容,您可以按以下方式禁用测试或整个类的交易管理:
如果您更喜欢让您的测试针对实际数据库运行,则可以使用`@AutoConfigureTestDatabase`注释,方法与`@DataJpaTest`相同。(请参见“Auto-configured Data JPA Tests”。)
Auto-configured Data JDBC Tests
@DataJdbcTest`类似于@JdbcTest`,但适用于使用Spring Data JDBC存储库的测试。默认情况下,它配置了一个基于内存的嵌入式数据库、JdbcTemplate`和Spring Data JDBC存储库。使用@DataJdbcTest`注释时,只扫描`AbstractJdbcConfiguration`子类,常规`@Component`和`@ConfigurationProperties`bean不被扫描。@EnableConfigurationProperties`可用于包含@ConfigurationProperties`bean。
|
由`@DataJdbcTest`启用的自动配置的列表可以found in the appendix。 |
默认情况下,Data JDBC测试是事务性的,并在每个测试结束时回滚。有关更多详细信息,请参阅Spring Framework参考文档中的{url-spring-framework-docs}/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions[相关章节]。如果不是您想要的内容,您可以为测试或整个测试类禁用事务管理,例如shown in the JDBC example。
如果您更喜欢让您的测试针对实际数据库运行,则可以使用`@AutoConfigureTestDatabase`注释,方法与`@DataJpaTest`相同。(请参见“Auto-configured Data JPA Tests”。)
Auto-configured Data R2DBC Tests
@DataR2dbcTest 与 @DataJdbcTest 类似,但适用于使用 Spring Data R2DBC 存储库的测试。默认情况下,它会配置一个内存嵌入式数据库、一个 R2dbcEntityTemplate 和 Spring Data R2DBC 存储库。在使用 @DataR2dbcTest 注解时,不会扫描常规 @Component 和 @ConfigurationProperties bean。可以使用 @EnableConfigurationProperties 来包括 @ConfigurationProperties bean。
|
可以通过 found in the appendix 查询由 |
默认情况下,Data R2DBC 测试是非事务性的。
如果您更喜欢让您的测试针对实际数据库运行,则可以使用`@AutoConfigureTestDatabase`注释,方法与`@DataJpaTest`相同。(请参见“Auto-configured Data JPA Tests”。)
Auto-configured jOOQ Tests
你可以像使用 @JdbcTest 一样使用 @JooqTest,但适用于与 jOOQ 相关的测试。由于 jOOQ 严重依赖于与数据库架构相对应的基于 Java 的架构,因此使用了现有的 DataSource。如果你想在它替换为内存数据库,可以使用`@AutoConfigureTestDatabase`来覆盖那些设置。(有关在 Spring Boot 中使用 jOOQ 的更多信息,请参阅 "Using jOOQ")。在使用 @JooqTest 注解时,不会扫描常规 @Component 和 @ConfigurationProperties bean。可以使用 @EnableConfigurationProperties 来包括 @ConfigurationProperties bean。
|
可以通过 found in the appendix 查询由 |
@JooqTest 配置了 DSLContext。以下示例展示了正在使用的 @JooqTest 注解:
默认情况下,JOOQ 测试是事务性的,并在每个测试结束时回滚。如果你不想要这样做,你可以禁用测试或整个测试类的事务管理,例如 shown in the JDBC example。
Auto-configured Data MongoDB Tests
你可以使用 @DataMongoTest 来测试 MongoDB 应用程序。默认情况下,它会配置一个 MongoTemplate、扫描 @Document 类,并配置 Spring Data MongoDB 存储库。在使用 @DataMongoTest 注解时,不会扫描常规 @Component 和 @ConfigurationProperties bean。可以使用 @EnableConfigurationProperties 来包括 @ConfigurationProperties bean。(有关在 Spring Boot 中使用 MongoDB 的更多信息,请参阅 "MongoDB")。
|
可以通过 found in the appendix 查询由 |
以下类示例展示了正在使用的 @DataMongoTest 注解:
Auto-configured Data Neo4j Tests
你可以使用 @DataNeo4jTest 来测试 Neo4j 应用程序。默认情况下,它会扫描 @Node 类,并配置 Spring Data Neo4j 存储库。在使用 @DataNeo4jTest 注解时,不会扫描常规 @Component 和 @ConfigurationProperties bean。可以使用 @EnableConfigurationProperties 来包括 @ConfigurationProperties bean。(有关在 Spring Boot 中使用 Neo4J 的更多信息,请参阅 "Neo4j")。
|
可以通过 found in the appendix 查询由 |
以下示例展示了在 Spring Boot 中使用 Neo4J 测试的典型设置:
默认情况下,Data Neo4j 测试是事务性的,并在每个测试结束时回滚。有关更多详细信息,请参阅 Spring Framework 参考文档中的[相关部分](docs/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions)。如果你不想要这样做,你可以为某个测试或整个类禁用事务管理,如下所示:
|
不支持通过响应访问进行的事务测试。如果你使用这种样式,你必须如上所述配置 |
Auto-configured Data Redis Tests
您可以使用 @DataRedisTest 来测试 Redis 应用程序。默认情况下,它会扫描 @RedisHash 课程和配置 Spring Data Redis 存储库。使用 @DataRedisTest 注释时,不会扫描常规的 @Component 和 @ConfigurationProperties bean。@EnableConfigurationProperties 可用于包含 @ConfigurationProperties bean。(有关将 Redis 与 Spring Boot 配合使用的更多信息,请参阅“Redis”。)
|
可以通过 found in the appendix 列出由 |
以下示例演示了 @DataRedisTest 注释的使用方法:
Auto-configured Data LDAP Tests
您可以使用 @DataLdapTest 来测试 LDAP 应用程序。默认情况下,它会配置内存中的嵌入式 LDAP(如果可用),配置一个 LdapTemplate,扫描 @Entry 课程和配置 Spring Data LDAP 存储库。使用 @DataLdapTest 注释时,不会扫描常规的 @Component 和 @ConfigurationProperties bean。@EnableConfigurationProperties 可用于包含 @ConfigurationProperties bean。(有关将 LDAP 与 Spring Boot 配合使用的更多信息,请参阅“LDAP”。)
|
可以通过 found in the appendix 列出由 |
以下示例演示了 @DataLdapTest 注释的使用方法:
内存中的嵌入式 LDAP 通常适用于测试,因为它速度快且不需要任何开发人员安装。但是,如果您希望针对真正的 LDAP 服务器运行测试,则应该排除嵌入式 LDAP 自动配置,如下面的示例中所示:
Auto-configured REST Clients
您可以使用 @RestClientTest 注释来测试 REST 客户端。默认情况下,它会自动配置 Jackson、GSON 和 Jsonb 支持,配置一个 RestTemplateBuilder 和一个 RestClient.Builder,并添加对 MockRestServiceServer 的支持。使用 @RestClientTest 注释时,不会扫描常规的 @Component 和 @ConfigurationProperties bean。@EnableConfigurationProperties 可用于包含 @ConfigurationProperties bean。
|
可以通过 found in the appendix 列出由 |
您想要测试的特定 bean 应当使用 @RestClientTest 的 value 或 components 属性进行指定。
在被测 bean 中使用 RestTemplateBuilder 时,如果在构建 RestTemplate 时已调用 RestTemplateBuilder.rootUri(String rootUri),则应该从 MockRestServiceServer 预期中省略根 URI,如下面的示例所示:
在被测 bean 中使用 RestClient.Builder 时,或在不调用 rootUri(String rootURI) 的情况下使用 RestTemplateBuilder 时,必须在 MockRestServiceServer 预期中使用完整的 URI,如下面的示例所示:
Auto-configured Spring REST Docs Tests
可以使用 @AutoConfigureRestDocs 注释在测试中结合 Mock MVC、REST Assured 或 WebTestClient 使用 {url-spring-restdocs-site}[Spring REST Docs]。它无需在 Spring REST Docs 中使用 JUnit 扩展。
可以使用 @AutoConfigureRestDocs 来覆盖默认输出目录(如果您使用的是 Maven,则为 target/generated-snippets;如果您使用的是 Gradle,则为 build/generated-snippets)。它还可用于配置显示在任何已记录 URI 中的主机、方案和端口。
Auto-configured Spring REST Docs Tests With Mock MVC
@AutoConfigureRestDocs 会自定义 MockMvc bean,以在对基于 servlet 的 web 应用程序进行测试时使用 Spring REST Docs。可以通过使用 @Autowired 注入该 bean,并且在测试中可以按平常使用 Mock MVC 和 Spring REST Docs 时的方式使用它,如下面的示例所示:
在测试中使用 @AutoConfigureRestDocs 代码:MyUserDocumentationTests[]
如果需要对 Spring REST Docs 配置拥有比通过 @AutoConfigureRestDocs 的属性提供的更大的控制权,那么可以使用 RestDocsMockMvcConfigurationCustomizer bean,如下面的示例所示:
在测试中使用 RestDocsMockMvcConfigurationCustomizer 代码:MyRestDocsConfiguration[]
如果您希望利用 Spring REST Docs 对参数化输出目录的支持,则可以创建一个 RestDocumentationResultHandler bean。自动配置使用此结果处理程序调用 alwaysDo,从而导致每个 MockMvc 调用自动生成默认片段。以下示例显示了 RestDocumentationResultHandler 定义:
Auto-configured Spring REST Docs Tests With WebTestClient
在测试响应式 Web 应用程序时,@AutoConfigureRestDocs 还可以与 WebTestClient 一起使用。您可以使用 @Autowired 注入它,并在测试中使用它,就像在使用 @WebFluxTest 和 Spring REST Docs 时通常会做的那样,如下例所示:
如果您需要对 @AutoConfigureRestDocs 的属性提供的 Spring REST Docs 配置进行更多控制,则可以使用 RestDocsWebTestClientConfigurationCustomizer bean,如下例所示:
在测试中使用 RestDocsMockMvcConfigurationCustomizer 代码:MyRestDocsConfiguration[]
如果您希望利用 Spring REST Docs 对参数化输出目录的支持,则可以使用 WebTestClientBuilderCustomizer 为每个实体交换结果配置使用者。以下示例显示了此类 WebTestClientBuilderCustomizer 的定义:
Auto-configured Spring REST Docs Tests With REST Assured
@AutoConfigureRestDocs 使得预先配置为使用 Spring REST Docs 的 RequestSpecification bean 可用于您的测试。您可以使用 @Autowired 注入它,并在测试中使用它,就像在使用 REST Assured 和 Spring REST Docs 时通常会做的那样,如下例所示:
在测试中使用 @AutoConfigureRestDocs 代码:MyUserDocumentationTests[]
如果您需要对 @AutoConfigureRestDocs 的属性提供的 Spring REST Docs 配置进行更多控制,则可以使用 RestDocsRestAssuredConfigurationCustomizer bean,如下例所示:
在测试中使用 RestDocsMockMvcConfigurationCustomizer 代码:MyRestDocsConfiguration[]
Auto-configured Spring Web Services Tests
Auto-configured Spring Web Services Client Tests
您可以使用 @WebServiceClientTest 测试使用 Spring Web Services 项目调用 Web 服务的应用程序。默认情况下,它配置一个模拟 WebServiceServer bean 并自动自定义您的 WebServiceTemplateBuilder。(有关在 Spring Boot 中使用 Web 服务的更多信息,请参见 "Web Services"。)
|
可以 found in the appendix 由 |
以下示例显示 @WebServiceClientTest 注释的使用情况:
Auto-configured Spring Web Services Server Tests
您可以使用 @WebServiceServerTest 测试使用 Spring Web Services 项目实现 Web 服务的应用程序。默认情况下,它配置一个 MockWebServiceClient bean,该 bean 可用于调用您的 Web 服务端点。(有关在 Spring Boot 中使用 Web 服务的更多信息,请参见 "Web Services"。)
|
可以 found in the appendix 由 |
以下示例展示了 @WebServiceServerTest 注释的用法:
Additional Auto-configuration and Slicing
每个 slice 都提供一个或多个 @AutoConfigure… 注释,主要定义作为 slice 一部分包含的自动配置。可以通过创建定制的 @AutoConfigure… 注释或在测试中添加 @ImportAutoConfiguration 来针对每个测试添加额外的自动配置,如下面的示例所示:
|
务必不要使用常规 |
或者,可以通过将额外的自动配置注册到按 META-INF/spring 存储的文件中针对任何 slice 注释的使用添加这些配置,如下面的示例所示:
com.example.IntegrationAutoConfiguration
在此示例中,com.example.IntegrationAutoConfiguration 已在使用 @JdbcTest 注释的所有测试上启用。
|
您可以在此文件中使用注释加上 |
|
slice 或 |
User Configuration and Slicing
如果您以合理的方式使用 structure your code,那么您的 @SpringBootApplication 类将作为测试配置使用 used by default。
因此,对应用程序主类重要的不是在其中散布特定的于其功能区域的设置配置。
假设您正在使用 Spring Data MongoDB,您依赖其自动配置,并且您已启用审核。您可以按如下方式定义您的 @SpringBootApplication:
由于此类是测试的源配置,因此任何 slice 测试都会尝试实际启用 Mongo 审核,但这绝对不是您想执行的操作。建议的方法是将该特定区域的配置移到一个独立的 @Configuration 类中,该类与您的应用程序处在同一级别,如下面的示例所示:
|
根据您的应用程序的复杂性,您可能拥有一个用于定制的单一的 |
测试 slice 将 @Configuration 类排除在扫描之外。例如,对于 @WebMvcTest,以下配置将不会在由测试 slice 加载的应用程序上下文中包含给定的 WebMvcConfigurer bean:
但是,以下配置将导致测试 slice 加载定制的 WebMvcConfigurer。
混乱的另一个来源是类路径扫描。假设在以明智的方式构建代码时,需要扫描其他包。应用程序可能类似于以下代码:
这样做实际上会覆盖默认组件扫描指令,其副作用是扫描这两个包,而不管你选择什么切片。例如,a`@DataJpaTest`似乎突然扫描了应用程序的组件和用户配置。同样,将自定义指令移到单独的类中是解决此问题的不错方法。
|
如果这不是你的选择,则可以在测试层次结构的某个位置创建一个`@SpringBootConfiguration`,以便改用。或者,你可以为测试指定一个来源,以禁用查找默认来源的行为。 |
Using Spock to Test Spring Boot Applications
Spock 2.2 or later can be used to test a Spring Boot application.To do so, add a dependency on a -groovy-4.0 version of Spock’s spock-spring module to your application’s build.spock-spring integrates Spring’s test framework into Spock.See the documentation for Spock’s Spring module for further details.
Testcontainers
Testcontainers library provides a way to manage services running inside Docker containers.It integrates with JUnit, allowing you to write a test class that can start up a container before any of the tests run.Testcontainers is especially useful for writing integration tests that talk to a real backend service such as MySQL, MongoDB, Cassandra and others.
Testcontainers can be used in a Spring Boot test as follows:
这将在运行任何测试之前启动运行 Neo4j 的 docker 容器(如果 Docker 在本地运行)。在大多数情况下,你需要配置应用程序以连接到容器中运行的服务。
Service Connections
服务连接是到任何远程服务的连接。Spring Boot 的自动配置可以获取服务连接的详细信息,并使用它们来建立与远程服务的连接。执行此操作时,连接详细信息优先于任何与连接相关的配置属性。
使用 Testcontainers 时,可以通过在测试类中注释容器字段为容器中运行的服务自动创建连接详细信息。
感谢`@ServiceConnection`,以上配置允许应用程序中的 Neo4j 相关 bean 与 Testcontainers 管理的 Docker 容器中运行的 Neo4j 通信。这是通过自动定义一个`Neo4jConnectionDetails`bean 来完成的,然后 Neo4j 自动配置使用该 bean,并覆盖任何与连接相关的配置属性。
|
你需要添加`spring-boot-testcontainers`module 作为测试依赖项,才能将服务连接与 Testcontainers 一起使用。 |
服务连接注释由注册为`spring.factories`的`ContainerConnectionDetailsFactory`类处理。`ContainerConnectionDetailsFactory`可以根据特定的`Container`子类或 Docker 映像名称创建一个`ConnectionDetails`bean。
以下服务连接工厂在中提供`spring-boot-testcontainers`jar:
| Connection Details | Matched on |
|---|---|
|
名为 "symptoma/activemq" 或`ActiveMQContainer`的容器 |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
类型为`KafkaContainer`或`RedpandaContainer`的容器 |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers named "otel/opentelemetry-collector-contrib" |
|
Containers named "otel/opentelemetry-collector-contrib" |
|
Containers of type |
|
类型为`MariaDBContainer`、 |
|
Containers of type |
|
Containers named "redis" |
|
Containers named "openzipkin/zipkin" |
|
默认情况下,将为给定的`Container`创建所有适用的连接详细信息 Bean。例如, |
默认情况下,`Container.getDockerImageName()`用于获取用于查找连接详细信息的名称。只要 Spring Boot 能够获取`Container`的实例,这种方法就有效,就像在上面的示例中使用`static`字段一样。
如果你正在使用`@Bean`方法,Spring Boot 将不会调用 Bean 方法来获取 Docker 镜像名称,因为这会导致急切初始化问题。相反,Bean 方法的返回类型用于找出应该使用哪个连接详细信息。只要你使用类型化的容器,例如`Neo4jContainer`或`RabbitMQContainer`,这种方法就有效。如果你使用`GenericContainer`,例如在 Redis 中使用,这种方法将停止工作,如下面的示例所示:
Spring Boot 无法从`GenericContainer`中判断使用哪个容器镜像,因此必须使用`@ServiceConnection`中的`name`属性来提供该提示。
你还可以使用`@ServiceConnection`的`name`属性来覆盖将使用哪个连接详细信息,例如在使用自定义镜像时。如果你使用 Docker 镜像`registry.mycompany.com/mirror/myredis`,你将使用`@ServiceConnection(name="redis")来确保创建`RedisConnectionDetails。
Test Utilities
在测试应用程序时通常有用的几个测试实用程序类打包在`spring-boot`中。
ConfigDataApplicationContextInitializer
ConfigDataApplicationContextInitializer`是一个`ApplicationContextInitializer,你可以将其应用于你的测试以加载 Spring Boot `application.properties`文件。当你不需要 `@SpringBootTest`提供的全部功能集时,可以使用它,如下面的示例所示:
|
仅使用`ConfigDataApplicationContextInitializer`不提供对`@Value("${…}") |
TestPropertyValues
TestPropertyValues`让你可以快速将属性添加到`ConfigurableEnvironment`或`ConfigurableApplicationContext。你可以用`key=value`字符串来调用它,如下所示:
OutputCapture
OutputCapture`是一个 JUnit `Extension,你可以用它来捕获`System.out`和`System.err`输出。要使用它,请添加`@ExtendWith(OutputCaptureExtension.class)`并将`CapturedOutput`注入到你的测试类构造函数或测试方法中,如下所示:
TestRestTemplate
`TestRestTemplate`是 Spring 的`RestTemplate`的一个方便的替代品,它在集成测试中很有用。你可以获得一个原生的模板或发送基本 HTTP 认证(包含用户名和密码)的模板。在这两种情况下,该模板都是容错的。这意味着它不会通过在 4xx 和 5xx 错误中抛出异常,以一种对测试友好的方式行事。相反,可以通过返回的`ResponseEntity`及其状态代码来检测到此类错误。
|
Spring Framework 5.0 提供了一个新注解 |
建议使用 Apache HTTP 客户端(版本 5.1 或更高版本),但这并非强制性的。如果类路径中存在该客户端,则 TestRestTemplate 会通过相应地配置客户端做出响应。如果确实使用 Apache HTTP 客户端,则会启用一些额外的测试友好型功能:
-
不会遵循重定向(因此你可以断言响应位置)。
-
忽略 cookie(因此模板是无状态的)。
TestRestTemplate 可以直接在你集成测试中实例化,如下面的示例所示:
或者,如果你在 WebEnvironment.RANDOM_PORT 或 WebEnvironment.DEFINED_PORT 中使用 @SpringBootTest 注解,则可以注入一个完全配置的 TestRestTemplate 并开始使用它。如果需要,可以通过 RestTemplateBuilder Bean 应用其他自定义。任何未指定主机和端口的 URL 会自动连接到嵌入式服务器,如下面的示例所示: