LoginSignup
2
0

More than 1 year has passed since last update.

【Kotlin】Exposedでテスト実行時に毎回テーブルの中身をTruncateする方法

Last updated at Posted at 2022-05-29

おはようこんにちはこんばんは。

Exposedを使った開発をしていてデータベーステストを実行したいときに、テスト関数を実行するごとにテーブルの中身を綺麗さっぱり消したいことがあります。

Laravelのようなフレームワークには RefreshDatabaseDatabaseTransactions のようなテスト実行時に入れたものをテストが終わったときに消してくれる仕組みがありますが、Exposedにはそのようなものは用意されてないので何らかの方法で消すしかありません。

毎回使ったテーブルの中身を消しに行くのはなかなか億劫なので、ベースになる抽象クラスを作っておいてそれを継承して使う形にして何もしなくても勝手に毎回中身が空になるテストを書いてみたので、そのメモです。

テストクラスのベースとなる抽象クラスでそれを実装してみる

今回はマイグレーションにflywayを使っているので、それのテーブルを除いて全てのテーブルを取得して中身を消すというものを書いてみました。

また、今回は kotlin.test を使っている前提で書いているので通常のJUnitなどを使っている場合は適宜読み替えて書き変えてください。

abstract class BaseTest {
  private fun setupApplication() {
    // DBへの接続のセットアップなどの必要な初期化処理を行う
  }

  @BeforeTest
  fun beforeBaseTest() {
    setupApplication()
    truncateDatabase()
  }

  private fun truncateDatabase() {
    transaction {
      // 外部キー制約があるテーブルをTRUNCATEするために一時的に制約を取る
      TransactionManager.current().exec("SET FOREIGN_KEY_CHECKS = 0")
      // flywayのテーブルを除いて全てのテーブルをTRUNCATEする
      db.dialect.allTablesNames().filterNot { it.contains("flyway_schema_history") }.forEach {
        TransactionManager.current().exec("TRUNCATE TABLE $it")
      }
      // 一時的に外していた制約を戻す
      TransactionManager.current().exec("SET FOREIGN_KEY_CHECKS = 1")
    }
  }
}

思ったより簡単ですね!

また、TRUNCATE時には外部キー制約周りの罠に引っかかることもあるので、(中身全部消しちゃうし良いでしょうということで) 一旦外部キー制約のチェックを強制的に外してTRUNCATE TABLEを実行してます。

テストを実行してみる

image.png

テストケースごとにしっかりテーブルの中身がTRUNCATEされてますね!

さいごに

普段業務や趣味でLaravelやRailsを触っていると、あれ?これも無いのぉ!?とびっくりすることもありますが、案外頑張れば意外と簡単に実装出来るのでExposedとKtorを使った開発もアリだなあと思いました。

2
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
2
0