使用Testcontainers与JUnit Jupiter无法连接Docker容器
解决Testcontainers PostgreSQL连接被拒绝问题
不要硬编码localhost:5432,使用容器动态生成的连接参数
Testcontainers会将容器的5432端口映射到主机的随机端口,而非固定的5432。直接写localhost:5432必然连接失败,必须通过容器实例提供的方法获取真实连接信息:@Container private static final PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15"); @BeforeAll static void setupDbProperties() { postgres.start(); // 将动态参数注入系统属性,供persistence.xml读取 System.setProperty("test.db.url", postgres.getJdbcUrl()); System.setProperty("test.db.user", postgres.getUsername()); System.setProperty("test.db.password", postgres.getPassword()); }对应的persistence.xml配置要使用变量引用:
<persistence-unit name="test-unit" transaction-type="RESOURCE_LOCAL"> <properties> <property name="jakarta.persistence.jdbc.url" value="${test.db.url}"/> <property name="jakarta.persistence.jdbc.user" value="${test.db.user}"/> <property name="jakarta.persistence.jdbc.password" value="${test.db.password}"/> </properties> </persistence-unit>确保容器在Weld初始化前启动
如果Weld在容器启动前就加载了持久化单元,会因连接信息未就绪导致失败。通过@TestInstance(PER_CLASS)让测试类只初始化一次,先启动容器再初始化Weld上下文:@TestInstance(TestInstance.Lifecycle.PER_CLASS) class PersistenceIntegrationTest { @Container private static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15"); private WeldContainer weldContainer; @BeforeAll void initDependencies() { postgres.start(); setupDbProperties(); // 复用上面的属性设置方法 weldContainer = new Weld().initialize(); } @AfterAll void cleanUp() { weldContainer.shutdown(); postgres.stop(); } }验证Docker环境与容器状态
- 打印容器的JDBC URL确认地址正确性:
System.out.println(postgres.getJdbcUrl()),正常输出应为jdbc:postgresql://localhost:xxxx/test(xxxx是随机端口)。 - 检查Docker Desktop是否正常运行,Linux环境需确保当前用户有权限访问Docker套接字(可通过
docker ps验证)。
- 打印容器的JDBC URL确认地址正确性:
无需手动设置网络别名
单容器测试场景下,网络别名是多余的,反而可能干扰容器地址解析,直接使用Testcontainers提供的动态连接参数即可。
内容的提问来源于stack exchange,提问作者user4695271
相关产品推荐
相关产品推荐

