前回 SpringBoot で作成した DB 操作クラスに対し DbUnit を使って簡単なテスト実施方法を紹介しました。
www.shookuro.com
前回の記事にも書きましたが、この自動テストの実行後にはテーブルのデータがテストで使用したデータに変わってしまいます。ちょっと困りますよね。
今回の記事では SpringBoot で DbUnit を使い、テスト完了時にテーブルデータをテスト実行前の状態に戻す方法について書いていきたいと思います。
DBバージョン は postgresql 9.5。SpringBootは 2.1.2。DBUnit は 2.6.0 です。
結論
テストのときは DataSource を TransactionAwareDataSourceProxy クラスでラップして Spring コンテナに Bean 登録します。
そして @Transactional アノテーションをテストクラスに付与し、トランザクション内でテストが実行されるようにします。
TransactionAwareDataSourceProxy とは
JavaDoc:
TransactionAwareDataSourceProxy (Spring Framework 5.0.6.BUILD-SNAPSHOT API)
簡単に言うと通常の DataSource への操作を中継してくれる DataSource です。このクラス自体も javax.sql.DataSource を impliments しています。
これを利用することにより、テストで実行される各トランザクションをまとめて大きな一つのトランザクションとして扱えるようにします。各トランザクションで Commit が行われたとしても、その外側の大きなトランザクションで Rollback すれば全体の変更が取り消されるということです。
実践編
(以降で記載している具体的なソースの内容は前回の記事を参照してください。)
DBUnit を使って Excel からデータを DB にロードする with Spring Boot - 山崎屋の技術メモ
テスト用 Configuration の作成
今回はサンプルなのでテストクラスと同じ階層に SampleTestConfiguration というクラスを作成しました。
実際のプロジェクトでは設定クラス用のパッケージを作ったほうが良いでしょう。
クラスの中身は次のように DataSourceBuilder でデータソースを作って TransactionAwareDataSourceProxy クラスのコンストラクタに引数で渡します。
package org.yyama; import javax.sql.DataSource; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; public class SampleTestConfiguration { @Bean public DataSource dataSource() { return new TransactionAwareDataSourceProxy( DataSourceBuilder .create() .username("postgres") .password("postgres") .url("jdbc:postgresql://localhost:5432/postgres") .driverClassName("org.postgresql.Driver") .build()); } }
クラスに @Component を付与してはいけません。テスト時以外の実行時にも DataSource に TransactionAwareDataSourceProxy が使用されてしまいます。
テストクラスで テスト用 Configuration を利用する
テストクラスで @Import を使って先ほど作成したテスト用 Configuration を読み込みます。
クラス宣言のあたりが
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class SampleTest_proc { ・ ・ ・
だったのを、
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest @Import(SampleTestConfiguration.class) public class SampleTest_proc { ・ ・ ・
にします。
加えて、ユニットテスト内の DB アクセスを大きなトランザクションで囲むため、@Transaction も付与します。こうなります。
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest @Import(SampleTestConfiguration.class) @Transactional public class SampleTest_proc { ・ ・ ・
これでユニットテスト完了時にテーブルデータが元の状態に戻るようになったはずです。
いちおう動作確認は欠かせません。
テスト前のテーブルの状態をこうしました。
postgres=# select * from member; id | name | age ----+---------+----- 49 | yyama | 25 50 | ryotsu | 38 51 | akimoto | 24 52 | bucho | 55 (4 行)
そしてテスト実行!
グリーン!!
そしてテーブルの中身は、、、
postgres=# select * from member; id | name | age ----+---------+----- 49 | yyama | 25 50 | ryotsu | 38 51 | akimoto | 24 52 | bucho | 55 (4 行)
テスト前と同じ!OK!!
自分でも勉強しながらやっているので、書いていることが本当なのかけっこう不安でしたw。
というわけで今回は成功です。
お疲れ様でした。
ユニットテスト完了時にテーブルデータを元に戻す方法まとめ
テスト時には DataSource を TransactionAwareDataSourceProxy でラップし、テストケースを大きなトランザクションとして実行し、テスト終了時には全てを Rollback することで、テスト前のデータ状態に戻す方法を紹介しました。
でわ!
Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発
- 作者: 株式会社NTTデータ
- 出版社/メーカー: 翔泳社
- 発売日: 2016/07/21
- メディア: 大型本
- この商品を含むブログ (1件) を見る
JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)
- 作者: 渡辺修司
- 出版社/メーカー: 技術評論社
- 発売日: 2012/11/21
- メディア: 単行本(ソフトカバー)
- 購入: 14人 クリック: 273回
- この商品を含むブログ (69件) を見る
- 作者: Kent Beck,和田卓人
- 出版社/メーカー: オーム社
- 発売日: 2017/10/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る