JavaでDBUnitというライブラリを使い、実際にDBと通信を行うテストを行う方法を説明します。
テーブルの構成
テストで使うDBは以下の通りとします。
- DB名...test
- テーブル名...animal
mysql> desc animal; +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(100) | YES | | NULL | | +-------+--------------+------+-----+---------+-------+ 2 rows in set (0.00 sec)
テーブルにデータは入っていません。
テストコード
このテーブルにレコードを追加し、レコードが追加されたかどうか確認する、という内容です。
テストコード中で使うinsert.xlsxとexpected.xlsxは以下のような内容です。

insert.xlsxの内容をanimalテーブルに挿入し、その結果がexpected.xlsxと同じようになっているかを確認します。
また、xlsxファイルにおけるシート名はDBにおけるテーブル名と同じにする必要があります。
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunit.ext.mysql.MySqlMetadataHandler;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Test;
import static org.dbunit.Assertion.assertEquals;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
public class InsertTest {
String url = "jdbc:mysql://localhost:3306";
String user = "testUser";
String password = "testPass";
@Test
public void insertTest() throws Exception {
Connection conn = DriverManager.getConnection(url, user, password);
IDatabaseConnection dbconn = new DatabaseConnection(conn, "test");
DatabaseConfig config = dbconn.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_METADATA_HANDLER, new MySqlMetadataHandler());
IDataSet dataset = new XlsDataSet(new File("data/insert.xlsx"));
DatabaseOperation.CLEAN_INSERT.execute(dbconn, dataset);
IDataSet expectedDataSet = new XlsDataSet(new File("data/expected.xlsx"));
ITable expectedTable = expectedDataSet.getTable("animal");
IDataSet actualDataSet = dbconn.createDataSet();
ITable actualTable = actualDataSet.getTable("animal");
assertEquals(expectedTable, actualTable);
}
}
エラーが発生しがちなポイント
このテストコードの実装に際して、何箇所かエラーが発生して解決に時間を使ってしまったので、メモしておきます。
ファイルがないというエラーが出る
このエラーが出る場合は
new File(ファイル名)
としているところで、ファイル名に絶対パスを指定してください。
NoSuchColumnExceptionというエラーが出る
org.dbunit.dataset.NoSuchColumnException: animal.ID - (Non-uppercase input column: ID) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
というエラーが発生し、解決に時間を取られました。
こちらは、以下の2行を追加することにより解決しました。
DatabaseConfig config = dbconn.getConfig(); config.setProperty(DatabaseConfig.PROPERTY_METADATA_HANDLER, new MySqlMetadataHandler());
assertEquals()でエラー
assertEquals()というメソッドはDBUnitではなくJUnitの方にも存在しています。
またその双方でオーバーロードされており、assertEquals()というメソッドが大量に存在します。
assertEquals()のところでエラーになる場合、間違ったassertEquals()メソッドを使っていないか確かめてみてください。
補足
通常DBUnitテストを行う場合、@Beforeアノテーションを付与したメソッドで現在DBにあるデータを退避させ、テスト終了後は@Afterアノテーションを付与したメソッドで退避させたデータをもとに戻す、という処理を行います。
今回はDBUnitの基本的な使い方を説明したかったので省きましたが、この方法は調べればすぐに出てくると思います。
また、
DatabaseOperation.CLEAN_INSERT.execute(dbconn, dataset);
としている箇所ではCLEAN_INSERTの代わりにINSERTを使えます。INSERTを使った場合は、animalテーブル上のデータは消去されませんが、CLEAN_INSERTを使うと、animalテーブルのデータが全て消去されてからデータが挿入されます。