使用Testcontainers时如何设置PostgreSQL的固定端口?
Testcontainers 固定 PostgreSQL 容器端口解决方案
Testcontainers 官方移除直接设置端口的特性,核心是为了避免端口冲突导致多测试用例并行执行失败,若你确定需要使用固定端口,可以通过修改容器创建参数实现端口绑定,修改后的配置类代码如下:
import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.PortBinding; import org.testcontainers.utility.DockerImageName; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; public class ContainerConfig { private static final PostgreSQLContainer postgresSQLContainer; // 自定义固定端口,可按需修改 private static final int CUSTOM_PG_PORT = 5432; static { DockerImageName postgres = DockerImageName.parse("postgres:13.1"); postgresSQLContainer = (PostgreSQLContainer) new PostgreSQLContainer(postgres) .withDatabaseName("test") .withUsername("root") .withPassword("root") .withReuse(true) // 新增端口绑定配置 .withCreateContainerCmdModifier(cmd -> cmd.getHostConfig() .withPortBindings(PortBinding.parse(CUSTOM_PG_PORT + ":5432"))); postgresSQLContainer.start(); } @SuppressWarnings("rawtypes") private static PostgreSQLContainer getPostgresSQLContainer() { return postgresSQLContainer; } @SuppressWarnings("unused") @DynamicPropertySource public static void registerPgProperties(DynamicPropertyRegistry propertyRegistry) { propertyRegistry.add("integration-tests-db", getPostgresSQLContainer()::getDatabaseName); propertyRegistry.add("spring.datasource.username", getPostgresSQLContainer()::getUsername); propertyRegistry.add("spring.datasource.password", getPostgresSQLContainer()::getPassword); // 手动拼接固定端口的JDBC连接地址 propertyRegistry.add("spring.datasource.url", () -> String.format("jdbc:postgresql://localhost:%d/test", CUSTOM_PG_PORT)); } }
注意事项
- 绑定的固定端口需要提前确认宿主机未被占用,否则会直接导致容器启动失败
- 开启
withReuse特性后,只要容器未被手动删除,后续测试复用容器时端口绑定不会变更 - 若不需要严格固定端口,更推荐使用原生的
getJdbcUrl()方法获取随机映射端口的连接地址,可避免端口冲突问题,适合多测试用例并行执行的场景
内容的提问来源于stack exchange,提问作者skyho
相关产品推荐
相关产品推荐

