如何为多个Jupiter测试创建通用的@Testcontainer?
问题根因
你的问题由两个常见的测试配置错误导致:
- 通过
System.setProperty设置Spring数据源属性的方式不稳定,多测试类场景下Spring上下文初始化时可能出现属性读取时序问题 - Hikari连接池默认的
maxLifetime超过了Testcontainers PostgreSQL容器的连接有效时长,导致池里缓存的连接被关闭后没有被及时淘汰
解决方案
修改抽象基类代码如下:
@SpringBootTest @AutoConfigureMockMvc @Testcontainers // 禁用Spring自动替换测试数据源,保证使用Testcontainers的数据库实例 @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) public abstract class ControllerAbstractTest { @Container private final static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:13") .withDatabaseName("my-test-db") .withUsername("a") .withPassword("a"); // 使用Spring提供的动态属性注入,替代System.setProperty @DynamicPropertySource static void registerPgProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl); registry.add("spring.datasource.username", postgreSQLContainer::getUsername); registry.add("spring.datasource.password", postgreSQLContainer::getPassword); // 缩短Hikari连接最大存活时间为10秒,主动淘汰失效连接 registry.add("spring.datasource.hikari.max-lifetime", () -> 10000); } // 其余原有方法保持不变 }
补充说明
- 静态修饰的
PostgreSQLContainer配合基类的@Testcontainers注解,会在整个测试运行周期内只启动一次容器,不会因测试类拆分重复创建或提前销毁 - 无需在子类额外添加
@Testcontainers注解,父类的注解会自动被子类继承 @DynamicPropertySource是Spring Boot 2.4+默认支持的特性,你当前使用的2.5.6版本无需额外引入依赖
内容的提问来源于stack exchange,提问作者Nikita Kozhukharov
相关产品推荐
相关产品推荐

