Spring Boot + Flyway + Testcontainers(mariaDB): Table "xxxx" 不存在

Spring Boot + Flyway + Testcontainers(mariaDB): Table "xxxx" doesn't exist

我在 Spring 引导项目中使用带有 mariaDB 数据库的 Testcontainers 进行单元测试。我最近将 Spring Boot 从 2.4.4 升级到 2.6.6,发现单元测试开始失败。在 Flyway 迁移发生后(创建了数据库模式)再次创建了 Testcontainers(?)。

我有点疑惑,想知道是否需要设置特定的配置才能使单元测试再次运行。

依赖如下

plugins {
    ...
    id 'org.springframework.boot' version '2.6.6'
    id "org.flywaydb.flyway" version "8.4.2"
    ...
}

dependencies {
    ...
    testCompileOnly 'junit:junit:4.13.2'
    testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.8.2'
    implementation  "org.flywaydb:flyway-core:8.1.0"
    implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.4'
    implementation "org.jooq:jooq:3.16.5"
    testImplementation "org.testcontainers:mariadb:1.16.2"
    ....

配置如下

spring.datasource.url=jdbc:tc:mariadb:10.5:///
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.username=""
spring.datasource.password=""

spring.jooq.sql-dialect=MARIADB

spring.flyway.enabled=true
spring.flyway.locations=filesystem:./src/main/resources/db/migration
spring.flyway.url=jdbc:tc:mariadb:10.5:///
spring.flyway.baseline-on-migrate=true

# logging
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE

日志信息如下

INFO 49309 --- [    Test worker] c.a.a.m.r.MyUnitTest   : Starting MyUnitTest using Java 11.0.11 on xxxxxxx with PID 49309 (started by user.name in /Volumes/code/sample/sample)
INFO 49309 --- [    Test worker] c.a.a.m.r.MyUnitTest   : The following 1 profile is active: "test"
INFO 49309 --- [    Test worker] trationDelegate$BeanPostProcessorChecker : Bean 'io.opentracing.contrib.spring.cloud.async.DefaultAsyncAutoConfiguration' of type [io.opentracing.contrib.spring.cloud.async.DefaultAsyncAutoConfiguration$$EnhancerBySpringCGLIB$e8860ae] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
WARN 49309 --- [    Test worker] i.o.c.s.t.c.TracerAutoConfiguration      : Tracer bean is not configured! Switching to NoopTracer
INFO 49309 --- [    Test worker] o.c.s.w.s.ServerTracingAutoConfiguration : Creating WebMvcConfigurer bean with class io.opentracing.contrib.spring.web.interceptor.TracingHandlerInterceptor
INFO 49309 --- [    Test worker] o.t.utility.ImageNameSubstitutor         : Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
INFO 49309 --- [    Test worker] o.t.d.DockerClientProviderStrategy       : Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
INFO 49309 --- [    Test worker] o.t.d.DockerClientProviderStrategy       : Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
INFO 49309 --- [    Test worker] org.testcontainers.DockerClientFactory   : Docker host IP address is localhost
INFO 49309 --- [    Test worker] org.testcontainers.DockerClientFactory   : Connected to docker: 
  Server Version: 20.10.13
  API Version: 1.41
  Operating System: Docker Desktop
  Total Memory: 7859 MB
INFO 49309 --- [    Test worker] o.t.utility.RegistryAuthLocator          : Credential helper/store (docker-credential-desktop) does not have credentials for index.docker.io
2022-05-16 09:18:36.309  INFO 49309 --- [    Test worker] o.t.utility.RyukResourceReaper           : Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
INFO 49309 --- [    Test worker] org.testcontainers.DockerClientFactory   : Checking the system...
INFO 49309 --- [    Test worker] org.testcontainers.DockerClientFactory   : ✔︎ Docker server version should be at least 1.6.0
INFO 49309 --- [    Test worker] org.testcontainers.DockerClientFactory   : ✔︎ Docker environment should have more than 2GB free disk space
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Creating container for image: mariadb:10.5
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container mariadb:10.5 is starting: 57036754c74fbb2440acd1f1796bc5cc6b8e5ba3e303b73e53ed666ebee34b18
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Waiting for database connection to become available at jdbc:mariadb://localhost:51394/test using query 'SELECT 1'
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container is started (JDBC URL: jdbc:mariadb://localhost:51394/test)
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container mariadb:10.5 started in PT6.247538S
INFO 49309 --- [    Test worker] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 8.2.0 by Redgate
INFO 49309 --- [    Test worker] o.f.c.i.database.base.BaseDatabaseType   : Database: jdbc:mariadb://localhost:51394/test (MariaDB 10.5)
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbClean        : Successfully dropped pre-schema database level objects (execution time 00:00.003s)
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbClean        : Successfully cleaned schema `test` (execution time 00:00.013s)
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbClean        : Successfully cleaned schema `test` (execution time 00:00.013s)
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbClean        : Successfully dropped post-schema database level objects (execution time 00:00.002s)
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Creating container for image: mariadb:10.5
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container mariadb:10.5 is starting: 1dfd0cd43d1d842ded36f12f7081fcaedc3768ff8dae2514a7ad8c3fba4a9bf6
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Waiting for database connection to become available at jdbc:mariadb://localhost:51457/test using query 'SELECT 1'
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container is started (JDBC URL: jdbc:mariadb://localhost:51457/test)
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container mariadb:10.5 started in PT6.413163S
INFO 49309 --- [    Test worker] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 8.2.0 by Redgate
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbValidate     : Successfully validated 3 migrations (execution time 00:00.016s)
INFO 49309 --- [    Test worker] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table `test`.`flyway_schema_history` ...
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbMigrate      : Current version of schema `test`: << Empty Schema >>
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbMigrate      : Migrating schema `test` to version "1.0 - create db schema"
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbMigrate      : Migrating schema `test` to version "1.1 - remove bad entries"
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbMigrate      : Migrating schema `test` to version "1.2 - remove old entries"
INFO 49309 --- [    Test worker] o.f.core.internal.command.DbMigrate      : Successfully applied 3 migrations to schema `test`, now at version v1.2 (execution time 00:00.127s)
INFO 49309 --- [    Test worker] o.s.s.web.DefaultSecurityFilterChain     : Will not secure any request
INFO 49309 --- [    Test worker] org.eclipse.jetty.util.log               : Logging initialized @20593ms to org.eclipse.jetty.util.log.Slf4jLog
INFO 49309 --- [    Test worker] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Creating container for image: mariadb:10.5
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container mariadb:10.5 is starting: 51aa6eb7e010bddd69d9e906cbc97cff242bd46a3d85a9d08dc1b85e6a35b70a
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Waiting for database connection to become available at jdbc:mariadb://localhost:51525/test using query 'SELECT 1'
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container is started (JDBC URL: jdbc:mariadb://localhost:51525/test)
INFO 49309 --- [    Test worker]  [mariadb:10.5]                        : Container mariadb:10.5 started in PT6.344117S
INFO 49309 --- [    Test worker] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
INFO 49309 --- [    Test worker] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2'. Database available at 'jdbc:mariadb://localhost:51525/test?user=test&password=***'
INFO 49309 --- [    Test worker] o.c.s.w.s.ServerTracingAutoConfiguration : Creating FilterRegistrationBean bean with TracingFilter mapped to [], skip pattern is "/api-docs.*|/swagger.*|.*\.png|.*\.css|.*\.js|.*\.html|/favicon.ico|/hystrix.stream|/actuator/(health|health/.*)"
INFO 49309 --- [    Test worker] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint(s) beneath base path '/actuator'
INFO 49309 --- [    Test worker] c.a.a.m.r.MyUnitTest   : Started MyUnitTest in 27.52 seconds (JVM running for 28.705)
INFO 49309 --- [    Test worker] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@6b41f56a testClass = MyUnitTest, testInstance = com.demo.sample.process.repository.MyUnitTest@55c989d7, testMethod = testProcess@MyUnitTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@6b04eb82 testClass = MyUnitTest, locations = '{}', classes = '{class com.demo.sample.sampleApplication, class com.demo.sample.process.config.TestAppConfig}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{classpath:application-integration.properties}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@775b1965, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@121f6d87, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@773ce2e2, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@4b69c0cb, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@411029bf, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@7aa81bef], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]; transaction manager [org.springframework.jdbc.support.JdbcTransactionManager@2da8b79d]; rollback [true]
INFO 49309 --- [    Test worker] org.jooq.Constants                       : 
                                      
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@  @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@
@@@@@@@@@@@@@@@@  @@  @@    @@@@@@@@@@
@@@@@@@@@@  @@@@  @@  @@    @@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@    @@  @@  @@@@  @@@@@@@@@@
@@@@@@@@@@    @@  @@  @@@@  @@@@@@@@@@
@@@@@@@@@@        @@  @  @  @@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Thank you for using jOOQ 3.15.1
                                      
INFO 49309 --- [    Test worker] org.jooq.Constants                       : 

jOOQ tip of the day: While you don't have to use jOOQ's code generator, there are *lots* of awesome features you're missing out on if you're not using it!

WARN 49309 --- [    Test worker] o.m.jdbc.message.server.ErrorPacket      : Error: 1146-42S02: Table 'test.my_db_table' doesn't exist

我不确定 SpringBoot 2.42.6 之间到底发生了什么变化,但我认为您需要完全删除 spring.flyway.url 属性。我只能猜测 属性 由于某种原因被较旧的 SpringBoot 忽略了。

删除 属性 后,Flyway 将使用 spring.datasource.url 值,并且只有一个 MariaDB 容器将由 Testcontainers 启动。