DBUnitの使い方
DBUnitにはさきほど説明したとおり、データのインポート/エクスポート、データの検証をする機能があります。弊社では、データのインポートおよび、インポートしたデータを削除する機能を使っていますので、この記事ではインポートおよび削除の使用方法について説明しようと思います。
インポートデータの記述方法
まずは、インポートするデータの記述方法についてです。ExcelとXMLでの記述方法がありますが、視覚的にも分かりやすく弊社でも採用している、Excelでの記述方法について説明させていただきます。
こんな風にテストデータが記述できます。Excelのシート名はテーブル名にあたり、1テーブル1シートという形です。1行目はカラム名で2行目以降はレコードになります。注意が必要なのは日付データ部分です。セルの表示形式が文字列の状態で"yyyy/mm/dd"と記述しても正常に読み込まれません。日付の形式を選択するように注意してください。
テストデータのインポート/クリーン処理の記述方法
続いて、DBUnitを使用してテストデータのインポートおよびクリーン処理を記述する方法について説明します。まず、以下のコードをさっとお読みいただければと思います。このコードは弊社のテストコードを参考にしています。
01: package com.oisix.codezine.dbunit.sample;
02:
03: import static org.junit.Assert.assertTrue;
04:
05: import java.io.File;
06:
07: import org.dbunit.IDatabaseTester;
08: import org.dbunit.JdbcDatabaseTester;
09: import org.dbunit.dataset.excel.XlsDataSet;
10: import org.dbunit.operation.DatabaseOperation;
11: import org.junit.After;
12: import org.junit.Before;
13: import org.junit.Test;
14:
15: /**
16: * How in Junit4 to write.
17: *
18: * @author yamada-shouhei
19: *
20: */
21: public class UseJunit4Sample {
22:
23: private IDatabaseTester databaseTester;
24:
25: @Test
26: public void sampleTest() {
27: assertTrue(true);
28: }
29:
30: @Before
31: public void setUp() throws Exception {
32: databaseTester = new JdbcDatabaseTester(
33: "oracle.jdbc.driver.OracleDriver",
34: "jdbc:oracle:thin:@xxx.xxx.xx.xx:xxxx:TESTDB", // @ip:port
35: "yamada", // user
36: "yamada", // pass
37: "yamada" // schema
38: );
39:
40: databaseTester.setDataSet(
41: new XlsDataSet(new File("src/com/oisix/codezine/dbunit/sample/UseJunitSample.xls"))
42: );
43: databaseTester.setSetUpOperation(DatabaseOperation.INSERT);
44: databaseTester.onSetup();
45: }
46:
47: @After
48: public void tearDown() throws Exception {
49: databaseTester.setTearDownOperation(DatabaseOperation.DELETE);
50: databaseTester.onTearDown();
51: }
52:
53: }
上記のコードは、dbunit.orgのGetting Startedを参考にしています。
JUnit 3では、DBTestCaseクラスを継承する書き方がポピュラーのようでしたが、JUnit 4の場合ではsetUp()に相当するメソッドが@Beforeアノテーション、tearDown()に相当するメソッドが@Afterアノテーションに置き換わりましたので、IDatabaseTesterを使う書き方がJUnit 4では一般的だと思います。
それでは、サンプルコードを説明します。
23: private IDatabaseTester databaseTester;
まず23行目のフィールドは、IDatabaseTesterのフィールド変数を宣言しています。このクラスはデータのインポート、クリーン処理を実装しているクラスのインターフェースです。25~28行目はサンプル用のテストケースなので読み飛ばします。
30: @Before
31: public void setUp() throws Exception {
32: databaseTester = new JdbcDatabaseTester(
33: "oracle.jdbc.driver.OracleDriver",
34: "jdbc:oracle:thin:@xxx.xxx.xx.xx:xxxx:TESTDB", // @ip:port
35: "yamada", // user
36: "yamada", // pass
37: "yamada" // schema
38: );
39:
40: databaseTester.setDataSet(
41: new XlsDataSet(new File("src/com/oisix/codezine/dbunit/sample/UseJunitSample.xls"))
42: );
43: databaseTester.setSetUpOperation(DatabaseOperation.INSERT);
44: databaseTester.onSetup();
45: }
続いて、set()メソッドを見ていきましょう。@Beforeアノテーションを付けています。このようにするとテストメソッド実行前に都度呼ばれるようになります。32行目~38行目はDB接続にJDBCのDriver Managerを使うテストデータのインポート、クリーンなどを行うときに使用するクラスのインスタンスを作っています。引数には以下を指定します。
- 33行目(引数1): driver-class
- 34行目(引数2): connection-url
- 35行目(引数3): user-name
- 36行目(引数4): password
- 37行目(引数5): schma-name
40: databaseTester.setDataSet(
41: new XlsDataSet(new File("src/com/oisix/codezine/dbunit/sample/UseJunitSample.xls"))
42: );
40~42行目はデータベースにインポートするDataSetをセットしています。Excelデータを使用する場合は、XlsDataSetを使います。他にもxml用のXmlDataSetなどもありますので、詳しくはJavadocを参照してください。
43: databaseTester.setSetUpOperation(DatabaseOperation.INSERT); 44: databaseTester.onSetup();
43行目ではonSetup()実行時の処理をDatabaseOperationクラスの定数で指定しています。引数にINSERTを指定しているので、44行目のonSetup()メソッド実行時に41行目でセットしたデータがデータベースにinsertされます。DatabaseOperationの定数には他にも種類がありますので、詳しくはDBUnitのJavadocを参照してください。
47: @After
48: public void tearDown() throws Exception {
49: databaseTester.setTearDownOperation(DatabaseOperation.DELETE);
50: databaseTester.onTearDown();
51: }
最後にtearDown()メソッドです。@Afterをアノテーションを付けているので、テストメソッド実行後に都度呼ばれます。49行目の文はonTearDown()実行時の処理をDatabaseOperationクラスの定数で指定しています。引数にDELETEを指定しているので、50行目のonTearDown()メソッド実行時に31行目のsetUp()で登録したデータがデータベースから削除されます。サンプルコードの説明は以上です。
コードは理解できたでしょうか。このサンプルでは説明のため、処理の共通化などは行っていませんが、setUp()時のデータベースへの登録処理、tearDown()でのデータベースからの削除処理は、テストクラスごとに記述してしまうと冗長なコードになってしまうので共通化するようにしてください。
