You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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验证)。
  • 无需手动设置网络别名
    单容器测试场景下,网络别名是多余的,反而可能干扰容器地址解析,直接使用Testcontainers提供的动态连接参数即可。

内容的提问来源于stack exchange,提问作者user4695271

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:49:58