takeda_san’s blog

KotlinとVRを頑張っていく方向。

Testcontainersのいつものテンプレを作りながらDAOのテストのやり方を考える

概要

いつも使うけど毎回下準備に時間がかかるTestcontainersの最小限のテンプレをSpring Boot+Doma+Kotlinで作りつつ、DAOのテストのパターンを考えます。

Testcontainersって何ですか

Testcontainersを使うことで、DockerコンテナをJUnitというかJavaコード上でセットアップできます。
ローカルでのテストでMySQLを使いたいみたいな場合に非常に便利です。

www.testcontainers.org

テンプレ

こちら。

github.com

ほぼこちらの記事をKotlinで書き直しただけでございます。
一度基底クラスとして、Testcontainersのセットアップの記述を書くだけで後は各テストクラス側で継承するだけであら不思議、DBを使ったテストができてしまう。
天才的発想。

Integration Tests With Spring Boot, TestContainers, Liquibase, and JUnit 5 | by Dmytro Timchenko | Javarevisited | Medium

DAOまわりのテストってどうやってますか?

ここからが本題でございます。
DAOまわりのテストをどうやっていますか?というお題。

Testcontainersを使う理由とちょっと考えなきゃいけないこと

Testcontainersを使う動機は、本番環境と同じ種類のDBを使えるという点に尽きます。
実際の本番同等とはいかないまでもDB特有の関数をそのまま使えるというのが、H2DBなどで代用する方法よりも優れています。

ちょっと考慮しなければいけない点がひとつ。
当たり前なんですが、動作環境としてDockerk環境が必要です。
各自ローカルに準備しなきゃいけないというのもあるのですが、CIなどでテストを実行するときにDockerコンテナ内でDockerコンテナを動かさないといけないので、アプリケーション内部のテストのやり方を意識してCIのセットアップする必要があります。
CI環境の変化や使用しているDockerイメージ、個人環境のちょっとした差異で突然テストが実行されなくなって、ハマるということも起こりえるので、その手間を覚悟しつつ使うという感じになると思います。

H2DBを使ったらいいのでは

じゃあ、安心と信頼のH2DBでDB部分を代用してテストしたらいいじゃないかという考え方。
DB特有の関数は、ステージング環境以降で確認するまで、ぐっと我慢。

でもでも、ステージング環境にデプロイして初めて実行されるSQLがあるというのも、ちょっと不安が残ります。 もっと気軽に検証できた方が安心ですね。

DBの種類の依存を小さくするために標準SQLのみでコードを書くという考え方もありますが、テストのためにプロダクションコードの実装の自由度を制限しては本末転倒な気がします。

じゃあ、どうすればいいのさ

素直にTestcontainersなりDokcerコンテナを使ったほうがいいというのが、今のところの考えです。
週に一度謎のエラーでテストが失敗するのも、調査の過程で良い勉強になります。
(無理やりな理由付け)