DEBUG.WIKI
搬瓦工;先看线路,再选 VPS;CN2 GIA · 对应线路套餐;查看线路 →
野草云;香港 200Mbps 峰值;不限月流量 · BGP VPS;查看套餐 →
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS

Testcontainers 已启动,R2DBC 却连旧地址:检查自定义工厂与模块

Flyway 能连接测试容器,R2DBC 却仍使用配置文件地址。分别检查自定义 ConnectionFactory 是否消费连接详情,以及测试类路径是否有 Testcontainers R2DBC 模块。

PostgreSQL 测试容器已经启动,Flyway 迁移也成功,R2DBC 却仍连接 spring.r2dbc.url 中的旧主机,报 UnknownHostException。不能仅凭这点认定 @ServiceConnection 没有生成连接详情:连接详情缺失、以及连接详情已存在但无人使用,会有相同的外部症状。

Spring Boot 4.0.0 的相关测试中,需要分开检查自定义 ConnectionFactory 和 Testcontainers 的 R2DBC 模块。JDBC 那一半正常,并不能证明 R2DBC 的依赖与创建路径都完整。

先看谁创建 ConnectionFactory

检查应用是否自己声明了 ConnectionFactory Bean,且只从 R2dbcProperties 读取 URL、用户名和密码。自定义 Bean 会让 Boot 对应的自动创建路径退让,@ServiceConnection 不会自动改写你在方法里读出的属性。

若没有必须自建工厂的理由,可评估恢复 Boot 自动配置。需要保留定制时,应让自定义工厂优先使用 R2dbcConnectionDetails 提供的 options,再在没有详情时回退到应用属性。不要直接把测试容器的密码写入全局系统属性来掩盖创建路径。

下面是已有工厂方法中的逻辑片段,details 表示已注入的可选连接详情,properties 表示原有属性对象:

var builder = (details != null)
        ? ConnectionFactoryBuilder.withOptions(
                details.getConnectionFactoryOptions().mutate())
        : ConnectionFactoryBuilder.withUrl(properties.getUrl())
                .username(properties.getUsername())
                .password(properties.getPassword());

片段中的 ConnectionFactoryBuilder 为 Boot 的 org.springframework.boot.r2dbc.ConnectionFactoryBuilder。保留项目原有的池化、驱动定制和最终构建步骤,不要为示例额外创建第二个工厂。

没有自定义工厂,再核对 R2DBC 模块

Testcontainers 2.x 的 PostgreSQL 模块不等于已经带上 R2DBC 适配。测试运行类路径还需包含同一 Testcontainers 版本系列的 org.testcontainers:testcontainers-r2dbc,以及数据库对应模块与实际 R2DBC 驱动。

1.x 与 2.x 的模块坐标有重命名,不能只改版本数字继续使用另一代名称。版本是否由 BOM 管理,应看当前构建的实际解析结果;不要为所有环境无条件复制某个历史版本。

分别确认容器对应的 R2dbcConnectionDetails 是否存在、工厂是否消费它,再看最终连接的主机和映射端口。查看这些信息时避免输出密码。验收应包含同一次测试中的 JDBC 与 R2DBC 实际查询,而不只检查容器健康或 Flyway 成功。

配置变更会影响测试连接目标。保留原工厂与依赖差异,确保受控测试不会因回退分支误连真实业务库;不要通过放通一个错误主机来让测试继续运行。