Testcontainers Support

除了 using Testcontainers for integration testing 之外,在开发时也可以使用它们。下一节将提供有关此内容的更多详细信息。

Using Testcontainers at Development Time

这种方法允许开发人员快速启动应用程序依赖的服务的容器,从而无需手动配置数据库服务器等内容。以这种方式使用 Testcontainers 提供的功能与 Docker Compose 类似,只不过你的容器配置用 Java 编写,而不是 YAML。

要在开发时使用 Testcontainers,你需要使用 “test” 类路径而不是 “main” 来启动应用程序。这将允许你访问所有已声明的测试依赖关系,并为你提供一个编写测试配置的自然位置。

要创建应用程序的可测试启动版本,你应该在 src/test 目录中创建一个 “Application” 类。例如,如果你的主应用程序在 src/main/java/com/example/MyApplication.java,你应该创建 src/test/java/com/example/TestMyApplication.java

TestMyApplication 类可以使用 SpringApplication.from(…​) 方法启动真正的应用程序:

你还需要定义要与应用程序一起启动的 Container 实例。为此,你需要确保将 spring-boot-testcontainers 模块已添加为 test 依赖关系。完成此操作后,你可以创建一个 @TestConfiguration 类,为要启动的容器声明 @Bean 方法。

你还可以使用 @ServiceConnection@Bean 方法添加注释,以创建 ConnectionDetails bean。有关受支持技术的详细信息,请参见 the service connections 部分。

典型的 Testcontainers 配置看上去如下:

Spring Boot 自动管理 Container bean 的生命周期。容器将自动启动和停止。

你可以使用 configprop:spring.testcontainers.beans.startup[] 属性来更改容器的启动方式。默认情况下,使用 sequential 启动,但如果希望并行启动多个容器,也可以选择 parallel

定义了测试配置后,可以使用 with(…​) 方法将其附加到测试启动器:

现在,你可以像启动任何常规 Java main 方法应用程序一样,启动 TestMyApplication 以启动你的应用程序及运行应用程序所需的容器。

你可以使用命令行上的 Maven goal spring-boot:test-run 或 Gradle 任务 bootTestRun 来执行此操作.

Contributing Dynamic Properties at Development Time

如果你想在开发期间从 Container @Bean 方法中提供动态属性,则可以通过注入 DynamicPropertyRegistry 来实现.此操作方式类似于你可以在测试中使用的 @DynamicPropertySource annotation.它允许你添加容器启动后即可使用的一些属性.

典型的配置看起来如下所示:

建议在可能的情况下使用 @ServiceConnection,但是对于尚未拥有 @ServiceConnection 支持的技术,动态属性可以作为有用的备用选择.

Importing Testcontainer Declaration Classes

使用 Testcontainers 时的一种常见模式是将 Container 实例声明为静态域.通常,这些域位于测试类中.它们也可以在一个父类中声明,或者在一个测试实现的接口中声明.

例如,以下 MyContainers 接口声明 mongoneo4j 容器:

如果你已经拥有此方式定义的容器或者你只是喜欢这种样式,那么你可以导入这些声明类,而不是将容器定义为 @Bean 方法.为此,请向你的测试配置类添加 @ImportTestcontainers 注释:

如果你不打算使用 service connections feature 但希望使用 @DynamicPropertySource,请从 Container 域中删除 @ServiceConnection 注释.你也可以向你的声明类中添加带 @DynamicPropertySource 注释的方法.

Using DevTools with Testcontainers at Development Time

当使用 devtools 时,你可以通过 @RestartScope 为 bean 和 bean 方法添加注释.当 devtools 重新启动应用程序时,这些 bean 将不会重新创建.这对 Testcontainer Container bean 特别有用,因为它们保留了在应用程序重新启动的情况下.

如果你正在使用 Gradle 并希望使用此功能,则需要将 spring-boot-devtools 依赖项的配置从 developmentOnly 更改为 testAndDevelopmentOnly.在 developmentOnly 的默认范围内,bootTestRun 任务将不会拾取你的代码中的更改,因为 devtools 未处于活动状态.