LoginSignup
1
0

More than 5 years have passed since last update.

JUnit にて Flyway を起動した際、schema_version テーブルが存在しないと表示される現象について

Posted at

概要

こちらの記事 を拝見させていただき、これは便利と、JUnit から DBUnit を使用してテストすることを考えました。しかしながら、下記構成にて JUnit からテストを実施した際、Flyway にて作成されているはずの、schema_version テーブルを DBUnit が確認できない現象が発生しました。

Spring Boot
JUnit
|---> Flyway (マイグレーションの DDL を実行)
|---> DBUnit (単体テスト用の CSV を投入)

現象の詳細

DBUnit で使用する TransactionAwareDatasourceProxy をコンテナに登録しています。

TestConfig.java
@TestConfiguration
@ComponentScan(basePackages = {"com.hoge.huga"})
public class TestConfig {

    @Autowired
    Environment environment;

    @Bean
    public TransactionAwareDataSourceProxy dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE");

        dataSource.setUsername("sa");
        dataSource.setPassword("");
        return new TransactionAwareDataSourceProxy(dataSource);
    }

ApplicationContext#getBean(TestConfig.class) にて上記をコンテナから取得しようとしておりましたが、下記を実施し、該当のクラスをコンテナに登録すると、getBean にて Bean を取得する前に実行される、DBUnit による flyway の schema_version テーブルのアクセスが失敗しました。

HogeTest.java
public class Hoge {
    @Before
    public void setUp() {
       ApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class);
    }
}
ログの内容
Caused by: org.h2.jdbc.JdbcSQLException: テーブル "schema_version" が見つかりません
Table "schema_version" not found; SQL statement:
SELECT "version_rank","installed_rank","version","description","type","script","checksum","installed_on","installed_by","execution_time","success" FROM "public"."schema_version" ORDER BY "version_rank" [42102-195]

原因

DBUnit のコネクション確立時に、単体テスト用の application.properties を読み込めていないためであると考えられます。
ApplicationContext のインスタンス化直前でブレークすると、IDE 上のログには下記が出力されており、schema_version のテーブルを作成されていることを確認できました。

DEBUG-2017-09-11 20:12:07,895---org.flywaydb.core.internal.dbsupport.SqlScript-40-main-Found statement at line 17: CREATE TABLE "PUBLIC"."schema_version" (
    "version_rank" INT NOT NULL,
    "installed_rank" INT NOT NULL,
    "version" VARCHAR(50) NOT NULL,
    "description" VARCHAR(200) NOT NULL,
    "type" VARCHAR(20) NOT NULL,
    "script" VARCHAR(1000) NOT NULL,
    "checksum" INT,
    "installed_by" VARCHAR(100) NOT NULL,
    "installed_on" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "execution_time" INT NOT NULL,
    "success" BOOLEAN NOT NULL
)

しかしながら、デバッグ実行して確認したところ、上記のエラーが発生した場合、@Autowired した Environment オブジェクトの ActiveProfile が NULL となっていました。
これは、下記の構成にて Profile で読み込む application.properties を切り替えているためであると考えられます。

・main
    |- java
         |- com.config
                 |- DevEnvironement.java (@PropertySource("classpath:application-dev.properties”) @Profile("dev”))
                 |- LocalEnvironement.java (@PropertySource("classpath:application-local.properties”) @Profile(“local”))
    |- resources
         |- application-dev.properties
         |- application-local.properties
・test
    |- resources
          |-  application.properties

補足
^^^^
コンテナに登録しないクラスでは、@Autowired ができないため、Environment オブジェクトを参照できません。
コンテナに登録していないオブジェクトにおいても、Environment#getProperty をするため下記のようなプロキシの形式にて Environment オブジェクトを取得しています。

HogeEnvironment.java
public HogeEnvironment {
private static Environment hogeEnvironment;

static {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(HogeApplication.class);
    hogeEnvironment = context.getEnvironment();

}

回避策

テストクラスにおいて、テストクラス用の application.properties を読み込むよう変更することで回避できることが確認できました。
この際、こちらの記事 にて紹介されている現象が発生するので、test/resources/application.properties の名称を変更して、application-unit.properties にしました。

UnitEnvironment.java
@Configuration
@Profile("unit")
@PropertySource("classpath:application-unit.properties")
public class UnitEnvironment  {
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0