在Spring Boot的测试中,Testcontainers会在无需显式的启动代码或注解的情况下自动启动

后端开发 2026-07-12

我在研究Testcontainers,以及在Spring Boot应用中使用的各种方法。遇到了一些奇怪的问题。我的测试本不应该通过,但它确实通过了,我不明白这是怎么回事。

我有下面的测试类,其中创建了一个带有 @ServiceConnection 标注的PostgreSQLContainer实例。我没有使用 @Testcontainers@Container 注解,也没有在代码中的任何位置启动我的容器。但是当我运行测试时,它却毫无问题地通过了。

  1. 那么我的PostgreSQLContainer是如何被启动的?
  2. 是谁在启动我的PostgreSQLContainer?
  3. @ServiceConnection 是否在启动我的容器?
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureRestTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.testcontainers.postgresql.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureRestTestClient
class DemoTest {

    @ServiceConnection
    private static final PostgreSQLContainer postgresContainer = new PostgreSQLContainer(
            DockerImageName.parse("postgres:18.2-alpine3.22"));

    @Test
    void container_is_running() {
        Assertions.assertTrue(postgresContainer.isRunning());
    }

    @Test
    void datasource_details_are_correct() {
        Assertions.assertEquals("org.postgresql.Driver", postgresContainer.getDriverClassName());
        Assertions.assertEquals("test", postgresContainer.getDatabaseName());
        Assertions.assertEquals("test", postgresContainer.getUsername());
        Assertions.assertEquals("test", postgresContainer.getPassword());
    }
}

我正在使用最新版本的Spring Boot,并引入了Testcontainer Postgres模块依赖。

解决方案

我做了一点调试,似乎 @ServiceConnection 是启动容器的那个人。@ServiceConnection 正在尝试使用 JdbcConnectionDetails 创建数据源,作为这个过程的一部分,它正在尝试在容器上获取驱动程序类名。在获取容器时,它会检查该容器是否是 Startable 的实例。如果是,那么它就直接对容器调用start方法。

似乎这一行为在文档中没有被记录。

以下截图供参考。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章