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

如何用Testcontainers实现多数据库集成测试并创建指定Catalog表

问题解决方法

问题原因

Hibernate的ddl-auto=create模式不会自动创建指定的catalog(MariaDB中catalog与database等价),只会在已存在的catalog下生成表。而Testcontainers启动的MariaDB容器默认仅包含你指定的test数据库,GE_events catalog不存在,导致Event表无法创建。

解决方案

方案一:通过Testcontainers初始化脚本提前创建catalog

放弃jdbc:tc:的简化URL配置,手动定义MariaDB容器并指定初始化脚本,在脚本中创建GE_events catalog:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, 
  properties = {"spring.jpa.hibernate.ddl-auto=create",
    "spring.jpa.show_sql=true",
    "javax.persistence.sql-load-script-source=data.sql"})
@RunWith(SpringRunner.class)
public class ServiceIntTest {

    // 定义MariaDB容器并指定初始化脚本
    @Container
    public static MariaDBContainer<?> mariaDBContainer = new MariaDBContainer<>("mariadb:latest")
            .withInitScript("init-catalog.sql");

    // 动态注入数据源属性
    @DynamicPropertySource
    static void setDatasourceProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", mariaDBContainer::getJdbcUrl);
        registry.add("spring.datasource.username", mariaDBContainer::getUsername);
        registry.add("spring.datasource.password", mariaDBContainer::getPassword);
        registry.add("spring.datasource.driver-class-name", () -> "org.testcontainers.jdbc.ContainerDatabaseDriver");
    }
}

在项目resources目录下创建init-catalog.sql文件,内容如下:

CREATE DATABASE IF NOT EXISTS GE_events;

方案二:通过JDBC URL参数指定初始化脚本

保持原有测试类结构,在JDBC URL中添加TC_INITSCRIPT参数指定初始化脚本:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, 
  properties = {"spring.jpa.hibernate.ddl-auto=create",
    "spring.jpa.show_sql=true",
    "javax.persistence.sql-load-script-source=data.sql",
    "spring.datasource.url= jdbc:tc:mariadb://localhost/test?TC_INITSCRIPT=classpath:init-catalog.sql",
    "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver"})
@RunWith(SpringRunner.class)
public class ServiceIntTest {
...
}

同样在resources下创建init-catalog.sql文件,内容为创建GE_events的SQL语句。

方案三:使用@Sql注解在测试前执行创建语句

无需额外脚本,直接在测试类上添加@Sql注解,在Hibernate执行DDL前创建catalog:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, 
  properties = {"spring.jpa.hibernate.ddl-auto=create",
    "spring.jpa.show_sql=true",
    "javax.persistence.sql-load-script-source=data.sql",
    "spring.datasource.url= jdbc:tc:mariadb://localhost/test",
    "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver"})
@RunWith(SpringRunner.class)
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, statements = "CREATE DATABASE IF NOT EXISTS GE_events;")
public class ServiceIntTest {
...
}

验证逻辑

上述方案都会在Testcontainers启动MariaDB容器后、Hibernate执行表生成逻辑前创建GE_events catalog。之后Hibernate会自动在GE_events下创建event表,同时在默认的test数据库下创建user表,满足测试需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:55:16