DbUnitNG プロジェクト日本語トップページ - SourceForge.JPで期待値のファイルとデータベースのテーブルをアサートするアノテーションを作りました。
@TableAssertです。
こんな感じ。
@TableAssert(names = "dept", pathname = "insert_expected.xml") @SetUpOperation(pathname = "dept.xml", value = DatabaseOperationType.DELETE_ALL) public void testTableAssert() { insert(); }
必須属性はnamesとpathnameです。
この2つだけなら、namesにデータベースのテーブル名を記述します。
つまり、今回はdeptテーブルと期待値ファイルをアサートします。
アサートは、期待値のファイルにあるカラムだけ比較します。
pathnameには期待値のファイルを記述します。この場合、「insert_expected.xml」が期待値のファイルです。
ファイル名だけであれば、テストクラスと同パッケージに配置します。
内容はDbUnitの形式です。
SQL文を直接記述することもできます。
@TableAssert(names = "dept", pathname = "org/dbunitng/sample/dao/insert_expected.xml", queries = "select dname, deptno, loc from dept") @SetUpOperation(pathname = "dept.xml", value = DatabaseOperationType.DELETE_ALL) public void testTableAssert2() { insert(); }
queries属性にはSQL文を記述します。その結果がDbUnitのITableとなります。ITableのテーブル名はnames属性に記述した名前になります。
つまり、この例ではSQL文の結果がITableとなり、テーブル名はdeptとなります。
XMLで表現すると以下のイメージです。
<dataset> <DEPT DEPTNO="1" DNAME="test" LOC="Osaka" /> </dataset>
これを実装するのに散々悩んだのですが、結局一番ダサい方法で実装しました。
ダウンキャスト。。。
ITestListener#onStart(ITestContext context)の引数ITestContextを実装クラスTestRunnerクラスにキャストしてます。
で、リスナーのリストにアクセスします。
リストを取得したら、DbUnitNGライブラリのリスナーが先頭に来るようにソートしてます。
TestRunner runner = (TestRunner) context; List<ITestListener> list = runner.getTestListeners(); Collections.sort(list, new Comparator<ITestListener>() { public int compare(ITestListener o1, ITestListener o2) { if (o1 instanceof DbUnitNGTestListener) { return -1; } else if (o2 instanceof DbUnitNGTestListener) { return 1; } return 0; } });
あーJavaなのにインタフェースの実装クラスを意識してダウンキャストなんて、一番ダサいプログラミングだよね。。。
他にいい方法が思いつかなかった。。。