この記事では、DB接続処理のプログラムをDBUnitでテスト自動化する方法を紹介します
- DBUnitの利用方法が知りたい
- DBと連結したテストコードを知りたい
- DBUnitを利用する際の注意点を知りたい
昨今では単体テストを自動化することが主流となっています。
ただ、「単体テストの自動化」と言っても、DBとの接続までテストするプロジェクトもあれば、DBとの接続をモック化して進めるプロジェクトもあり、検証方法は様々です。
単体テストでSQLの妥当性まで確認できたほうが早くバグを発見できるため、簡単に実現できるならDB接続も含めてテストしたいですよね。
しかし、DBの接続までテストする場合、テスト用のDBの準備やテストで作成されたデータの廃棄方法など調べることが多く難しく感じてしまいます。
そこでこの記事では、単体テストの自動化でDB接続を行うときのテスト検証方法をまとめました。
DBUnitの導入から、テストコードの書き方、DBUnitの注意点にいたるまで解説しています。
テストを自動化する際に役立つ内容となってますので、ぜひ最後までご覧ください。
利用技術の紹介
当記事で利用する技術を簡単に紹介します。(すでにご存知のかたは読みとばしてください。)
JUnit
Javaプログラムの単体テストを行うためのフレームワーク。テストコードの記述と結果の確認が簡単になる。
DBUnit
DBを操作する単体テストを簡単にするためのフレームワーク。JUnitを拡張したもので、データベースにアクセスするプログラムの単体テストが簡単に実現できる。
DB接続処理のテスト実現方法
ここから、DB接続のテストを自動化する方法を解説します。
今回は、「データ登録処理を行うメソッド実行後、DBに登録された結果が正しいか」を検証するテストケースを例として解説します。
DBUnitの導入
DBUnitは、Mavenでインストールします。
pom.xmlに以下を記述します。
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.7.0</version>
<scope>test</scope>
</dependency>Mavenのインストールコマンドを実行し、DBUnitをインストールします。
mvn installPOIの導入
DBUnitを使ったテストでは、テスト時に必要なテストデータを準備できます。投入するデータは、xmlまたはExcelで定義が可能です。
本記事では、直感的にわかりやすいExcelで定義し進めます。DBUnitでは、ExcelのデータをロードするためにPOI(*)を利用しているため、インストールしておきます。
pom.xmlのPOIの情報を記述します。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
<scope>test</scope>
</dependency>JavaでExcelファイルを読み書きするフリーのライブラリ。Excelがインストールされていない環境でもExcelファイルを読み書きすることが特徴。
テストデータの準備
テストに必要なデータを準備します。
Excelでテストデータを定義するときはシート名を「テーブル名」にします。複数テーブルを読み込ませたい場合は、シートをテーブル数分用意します。

各シートの内容は一行目がテーブル項目、二行目以降はデータとして扱われます。
DB接続処理のテストコード
DB接続を含めたテストコード全体はこちらです。正しくデータが取得できることを想定したテストケースです。
import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.dbunit.dataset.excel.XlsDataSet;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class SelectTest extends DBTestCase {
public SelectTest() {
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "oracle.jdbc.driver.OracleDriver");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:oracle:thin:@localhost:1521:yourdb");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "username");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "password");
}
@Override
protected IDataSet getDataSet() throws Exception {
// Excelファイルからテストデータセットをロード
return new XlsDataSet(new FileInputStream("path/to/your/dataset.xls"));
}
@Override
protected DatabaseOperation getSetUpOperation() throws Exception {
// テスト前にデータセットをデータベースにインサート
return DatabaseOperation.CLEAN_INSERT;
}
@Override
protected DatabaseOperation getTearDownOperation() throws Exception {
// テスト後にデータベースをクリーンアップ
return DatabaseOperation.DELETE_ALL;
// return DatabaseOperation.NONE;
}
public void testSelect() throws Exception {
// データベース接続を取得
Connection connection = getConnection().getConnection();
try {
// ※ここでデータ登録処理のメソッドを実行したとする
// example.testInsert(); ←実行メソッド例
// ---------
// 結果を検証
// ---------
// SELECT文を実行
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table WHERE id = 1");
// 取得された各項目の値が期待値通りか検証
assertTrue("Result set is empty", resultSet.next());
assertEquals("Test Name 1", resultSet.getString("name"));
assertEquals(123, resultSet.getInt("value"));
// 結果セットに次の行がないことを確認
assertFalse("Result set contains more than one row", resultSet.next());
} finally {
// リソースをクリーンアップ
connection.close();
}
}
}順番にポイントを解説していきます。
ポイント1:DBTestCaseを継承
DBUnitを利用する場合テストクラスは、「DBTestCase」 を継承します。
public class SelectTest extends DBTestCase {ポイント2:テストデータのロード
テストデータのロードは、DBTestCaseからオーバーライドされたメソッドで行います。
@Override
protected IDataSet getDataSet() throws Exception {
// Excelファイルからテストデータセットをロード
return new XlsDataSet(new FileInputStream("path/to/your/dataset.xls"));
}
@Override
protected DatabaseOperation getSetUpOperation() throws Exception {
// テスト前にデータセットをデータベースにインサート
return DatabaseOperation.CLEAN_INSERT;
}「getDataSet」メソッドの中でデータをロード、「getSetUpOperation」メソッドでデータセットの取り扱い方法を設定します。
今回はテスト前にデータを登録するモードとしました。
ポイント3:DBとの接続テスト
接続情報の設定
public SelectTest() {
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "oracle.jdbc.driver.OracleDriver");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:oracle:thin:@localhost:1521:yourdb");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "username");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "password");
}DBと接続するので、接続情報を設定します。
DRIVER_CLASSはoracleに設定していますが、利用するDBに合わせて変更してください。
DBに登録された結果のテスト
public void testSelect() throws Exception {
// データベース接続を取得
Connection connection = getConnection().getConnection();
try {
// ※ここでデータ登録処理のメソッドを実行したとする
// example.testInsert(); ←実行メソッド例
// ---------
// 結果を検証
// ---------
// SELECT文を実行
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table WHERE id = 1");
// 取得された各項目の値が期待値通りか検証
assertTrue("Result set is empty", resultSet.next());
assertEquals("Test Name 1", resultSet.getString("name"));
assertEquals(123, resultSet.getInt("value"));
// 結果セットに次の行がないことを確認
assertFalse("Result set contains more than one row", resultSet.next());
} finally {
// リソースをクリーンアップ
connection.close();
}
}SQLで取得された結果の値を比較しています。取得件数が1件であることを確認するため、「resultSet.next()」がFalseを返すことも検証しています。
ポイント4:テストデータのクリア
@Override
protected DatabaseOperation getTearDownOperation() throws Exception {
// テスト後にデータベースをクリーンアップ
return DatabaseOperation.DELETE_ALL;
// return DatabaseOperation.NONE;
}DBUnitでは、「getTearDownOperation」メソッドで、テスト完了後にテストデータをどのように取り扱うかを設定します。
通常、テストで利用したデータは元にもどすため、「DatabaseOperation.DELETE_ALL」を設定しデータをクリアしています。ここでクリアされるデータは「getDataSet」でロードしたテーブルに対して実行されます。
テスト後にデータベースに対して何もしたくない場合は、「DatabaseOperation.NONE」を設定します。
まとめ
- 「テストデータのロード」、「テスト」、「テストデータのクリア」の3ステップでテスト
- DBとの接続テストは、開発者と独立したテスト用のスキーマが必要
DBとの接続部分のテストは、DBUnitを利用することで簡単にテストを自動化できます。
テスト用のスキーマの準備が必要ですが、開発者と独立したスキーマを用意することで想定外のデータによるテスト失敗が防止でき、テストの信頼性が向上します。
ロードするテストデータをExcelで定義できるため、データのメンテナンスもしやすく利便性が高いです。
ただし、DBUnitが内部的に利用しているPOIのバージョンが一致しない場合は予期せぬエラーに遭遇するため注意が必要です。
本記事が皆様の参考になれば幸いです。
関連記事:LambdaをJavaで作成するには?環境構築方法からデプロイ方法まで徹底解説!



コメント