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

Spring Boot Testcontainers启动多个PostgreSQL实例问题咨询

问题根源

你现在的问题是同时混用了两种Testcontainers使用方式:手动创建PostgreSQLContainer实例,又通过jdbc:tc:前缀的URL触发了Testcontainers JDBC驱动自动创建容器,导致两个PostgreSQL实例启动,且版本不一致。此外测试代码里还存在属性key错误、Flyway用户名密码搞反的问题,进一步加剧了异常。


解决方案二选一即可

方案一:手动管理Testcontainers容器(推荐,更灵活)

完全由你控制容器版本与配置,不依赖JDBC驱动自动创建容器。

1. 修正测试代码

@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers
class SpringTestJenkinsApplicationTests {

    @Container
    private static final PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:15.2-bullseye")
            .withDatabaseName("postgres")
            .withUsername("root")
            .withPassword("root");

    @DynamicPropertySource
    public static void overrideProps(DynamicPropertyRegistry registry) {
        // 直接使用容器原生JDBC URL,无需添加tc前缀
        final String jdbcUrl = postgreSQLContainer.getJdbcUrl();
        System.out.println(jdbcUrl);

        // 修正属性key:去掉末尾多余的=
        registry.add("spring.datasource.url", () -> jdbcUrl);
        registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
        registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
        
        // 修正Flyway用户名密码(之前搞反了)
        registry.add("spring.flyway.url", () -> jdbcUrl);
        registry.add("spring.flyway.user", postgreSQLContainer::getUsername);
        registry.add("spring.flyway.password", postgreSQLContainer::getPassword);
    }

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void getAllMessages() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/v1/api/message")
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andReturn();
    }
}

2. 修正测试配置文件

server:
  port: 8080
spring:
  application:
    name: chat-api
  datasource:
    # 删除Testcontainers驱动配置,改用原生PostgreSQL驱动
  jpa:
    hibernate: # 修正拼写错误:原配置是hibernates
      ddl-auto: create
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQL95Dialect
        format_sql: true
    show-sql: false
  flyway:
    schemas: public
    enabled: false
    default-schema: public

方案二:用Testcontainers JDBC驱动自动管理容器

无需手动创建容器,由JDBC驱动自动创建并管理,只需在URL中指定版本。

1. 修正测试代码

@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers
class SpringTestJenkinsApplicationTests {

    @DynamicPropertySource
    public static void overrideProps(DynamicPropertyRegistry registry) {
        // 直接指定带版本的tc格式URL
        final String jdbcUrl = "jdbc:tc:postgresql:15.2-bullseye:///postgres?loggerLevel=OFF";
        System.out.println(jdbcUrl);

        registry.add("spring.datasource.url", () -> jdbcUrl);
        registry.add("spring.datasource.username", () -> "root");
        registry.add("spring.datasource.password", () -> "root");
        
        registry.add("spring.flyway.url", () -> jdbcUrl);
        registry.add("spring.flyway.user", () -> "root");
        registry.add("spring.flyway.password", () -> "root");
    }

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void getAllMessages() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/v1/api/message")
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andReturn();
    }
}

2. 保留配置文件的驱动设置

server:
  port: 8080
spring:
  application:
    name: chat-api
  datasource:
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
  jpa:
    hibernate: # 修正拼写错误
      ddl-auto: create
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQL95Dialect
        format_sql: true
    show-sql: false
  flyway:
    schemas: public
    enabled: false
    default-schema: public

问题原因复盘

  1. 手动创建postgres:15.2-bullseye容器的同时,又使用jdbc:tc:前缀URL,触发JDBC驱动自动创建默认版本(9.6.12)的容器,导致双实例启动。
  2. 动态属性key末尾多余的=,导致部分配置未生效,加剧版本不一致问题。
  3. Flyway的用户名与密码配置搞反,可能引发连接失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:44:55