我正在开发基于 Testcontainers 解决方案的系统/集成测试。我需要使用我们自己的数据库 PostgreSQL 映像和已经应用的数据库模式。
出于这个原因,我正在使用 Testcontainers GenericContainer。
private static final GenericContainer postgresDb = new GenericContainer(POSTGRES_IMAGE).withExposedPorts(5432);
我正在使用 Spring Boot 开发测试,因此我创建了抽象类,它将为所有测试保存此配置
@ActiveProfiles("test")
@SpringBootTest
public abstract class AbstractTests {
private static final DockerImageName POSTGRES_IMAGE = DockerImageName.parse("docker-name:latest");
private static final GenericContainer postgresDb;
static {
postgresDb = new GenericContainer(POSTGRES_IMAGE)
.withExposedPorts(5432);
postgresDb.withStartupTimeout(Duration.ofSeconds(30))
.start();
}
@DynamicPropertySource
static void properties(DynamicPropertyRegistry registry) throws InterruptedException {
final String s = "jdbc:postgresql://"+ postgresDb.getHost() +":"+ postgresDb.getMappedPort(5432) + "/test";
registry.add("spring.datasource.url", () ->s);
}
}
但是,问题是当测试运行时,容器仍在启动。这 withStartupTimeout(Duration.ofSeconds(30)) 出于某种原因不起作用。
当我在属性方法处停止调试并花几秒钟来启动容器时,所有测试都运行良好。
当测试失败时,我会看到下一个日志:
org.postgresql.util.PSQLException: FATAL: the database system is starting up
如果我放 Thread.sleep(..) 它也可以,这不是更好的解决方案。
什么是等待的正确解决方案或知道容器准备好的正确策略是什么?