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

使用Flyway Testcontainers测试迁移脚本校验数据时Repository未初始化如何解决

问题根因

你遇到的报错存在两个核心诱因:

  • 测试类同时标注@SpringBootTest和@DataJpaTest导致Spring上下文配置冲突,JPA相关的Repository Bean没有正常初始化,所以teamRepository注入失败,抛出lateinit未初始化异常
  • 手动创建的Flyway实例使用独立的Testcontainers数据源,和Spring上下文管理的JPA数据源不统一,哪怕注入成功也会查询到错误的数据库实例

解决方案

  1. 修正测试类注解冲突
    删除重复的测试注解,根据测试场景二选一:
  • 若仅需要测试JPA仓库+数据库迁移,保留@DataJpaTest,新增注解关闭Spring默认的测试内存数据库替换逻辑:
@DataJpaTest
@ActiveProfiles("test")
@Import(FlywayCallback::class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class DatabaseMigrationScriptIntegrationTest {
// 原有类内容
}
  • 若需要加载完整的Spring Boot上下文,删除@DataJpaTest,仅保留@SpringBootTest即可。
  1. 统一全局数据源配置
    不要在测试代码中手动创建Flyway实例,将Testcontainers MySQL的配置写入application-test.properties,让Spring Boot自动管理Flyway、DataSource、JPA的数据源,保证三者使用同一个数据库实例:
# application-test.properties
spring.datasource.url=jdbc:tc:mysql://localhost:3306/testdb
spring.datasource.username=testing
spring.datasource.password=testing
spring.flyway.locations=classpath:db/migration,classpath:db/callback
spring.flyway.target=10

修改后可以直接注入Spring管理的Flyway实例,不需要自己写创建逻辑。

  1. 可选方案(保留手动创建Flyway的逻辑)
    可以放弃使用Spring注入的Repository,直接用JdbcTemplate连接Flyway使用的数据源做查询校验,无需依赖Spring上下文的Repository注入:
@Test
fun runSqlInsertsAfterMigrationAndReadData() {
    val runAllMigrations = setFlywayConfigurationWithVersion("10")
    val migrate = runAllMigrations.migrate()
    // 直接用Flyway的数据源创建JdbcTemplate查询
    val jdbcTemplate = JdbcTemplate(runAllMigrations.configuration.dataSource)
    val email = jdbcTemplate.queryForObject("select email from team where id = ?", String::class.java, "12345")
    Assertions.assertThat(migrate.migrationsExecuted == 10)
    assertTrue(email == "someone@someone.com")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:24:08