SpringBootで実際に起動してあるDBを使ったユニットテストをしようとすると、デフォルトだと動かないようです。
正確にはEmbeddedDataSourceBeanFactoryPostProcessor
(ログだと長すぎるのでbeddedDataSourceBeanFactoryPostProcessor
として表示される)やEmbeddedDatabaseFactory
が起動して組込みDBとして動こうとするようです。(詳しい挙動はよくわかりませんでした)
回避方法としては、実際のDBを使用してテストする、Flyway + H2のインメモリDBを使用する、TestContainersを使用して起動後にJDBC_URLを上書きする等が必要です。
今回の記事では、実際のDBを使用してテストする方法を残します。
環境
- Java
- 17
- org.springframework.boot
- 2.4.5
- org.postgresql
- 42.2.23
設定ファイルで制御する
設定ファイルに組込みDBの無効化設定をすることで、実際のDBに対して接続できます。
spring.test.database.replace: none # any, AUTO_CONFIGURED が設定できます。
上の設定をすることで、各テストクラスに対して下のアノテーションが追加されているものと同じ状態になります。ただしコードで設定してしまうと、H2で行うテストとの切り替えが面倒になってしまいますので、設定ファイルで切り替えるようにした方がよいでしょう。
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
ソースコード
終わりに
もともとFlyway + H2でテストをしていたこともあり、実際のDBでテストする方法に気付けませんでした。
画像のとおり、設定ファイル上はURLをjdbc:postgresql://127.0....
と設定しているのに、テスト上有効になっているURLがjdbc:h2:mem:6f9309e0-...
とH2の設定で上書きされていたので、かなり混乱していました…。
ただ、何が原因でこれが起こっているのかが正直分かっていません。職場でテストしていた時はこの設定を追加していないはずなのですが…。
こういう細かいところの挙動は全然抑えられてないので、Springはまだまだ勉強することがありますね。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考情報
- testing - Spring-boot-starter-test cannot run database integration test - Stack Overflow
- AutoConfigureTestDatabase.Replace (Spring Boot 2.5.6 API) - Javadoc