ここ数日Arquillian Persitence Extensionのエントリが続いてますが、基本的には
ドキュメントのことを試して書いてるだけです…(^^;
今日はいくつかのオプションを試してみたメモです。
テーブル比較にて除外したいカラムがある場合
昨日書いた「Arquillian Persistence Extensionでテーブルの比較テストに挑戦」でテーブルの元データと、プログラムで処理された後に、こうなるだろう、という期待データとを比較することをやりました。
昨日のサンプルだと超簡易なテーブルなのでいいのですが、通常業務系のDBだと登録日時や更新日時があったりするので期待データを書くが難しかったりします。
保存された時間の分・秒書くなんてナンセンスすぎるし…。で、そんなときはShouldMatchDataSetアノテーションの属性にある「excludeColumns」を使えばいいようです。
試しに昨日のプログラムを以下のように変えて
@Test @UsingDataSet("dataset.xml") @ShouldMatchDataSet(value = "expected_dataset.xml", excludeColumns={"name"} ) //←nameカラム比較から除外してみる public void データベースの更新テスト(){ MyMeibo myMeibo = meibo.find(0002); assertThat(myMeibo.getName(), is("makimaki")); //取得できるのはmakimakiだよね? //ID 0002のレコードの名前をmakimakiからmakiへ変更するよー myMeibo.setName("maki"); //更新してみるねー meibo.edit(meibo); }
わざと昨日の失敗パターンデータでテストしてみました。
<?xml version="1.0" encoding="UTF-8"?> <dataset> <mymeibo id = "0001" name = "horikita" /> <mymeibo id = "0002" name = "makidayo" /> </dataset>
上記テストプログラム的には「IDが0002のデータのnameをmaki」にしたので、期待データが「makidayo」となっているとテスト失敗するのですが、「name」カラムの比較を除外しているので、成功します。おー。
テーブルの元データはそのままにしたい場合
Arquillianを初めて触ったときに書いた「Arquillian Persistence Extensionを触ってみる」は実行すると、元々登録されていたデータに加えてdataset.xmlのデータをinsertして、その後、テーブルデータが削除されます。
ここら辺の挙動はテスト内容によって変えたい場合があると思います。例えば元のデータを消さずにxmlファイルで追加したデータだけを削除したい場合は@Cleanupアノテーションを利用して以下のように書けました。
@Test @UsingDataSet("dataset.xml") @Cleanup(phase= TestExecutionPhase.AFTER, strategy= CleanupStrategy.USED_ROWS_ONLY) //テスト後、元データは残して使ったデータだけ消してね @ShouldMatchDataSet("expected_dataset.xml") public void データベースの更新テスト(){ MyMeibo myMeibo = meibo.find(0002); assertThat(myMeibo.getName(), is("makimaki")); //取得できるのはmakimakiだよね? //ID 0002のレコードの名前をmakimakiからmakiへ変更するよー myMeibo.setName("maki"); //更新してみるねー meibo.edit(meibo); }
言葉で書くとわかりにくいですね(^^;
以下のような流れとなりました。
テーブルに元々入ってるデータ
| ID | NAME |
| 0000 | kikutaro |
テストで追加するデータ(@UsingDataSetアノテーションで入れるデータ)
| ID | NAME |
| 0001 | horikita |
| 0002 | makimaki |
テスト実行時(元データに@UsingDataSetのデータが追加された)
| ID | NAME |
| 0000 | kikutaro |
| 0001 | horikita |
| 0002 | makimaki |
テスト完了後
| ID | NAME |
| 0000 | kikutaro |
うーむ、すごい。アノテーションだけでこういう設定ができるのが楽です。
テスト実行前にテーブルの元データを消して欲しい場合
元々のテーブル状態を気にせずに、テスト実行時には必ず事前に消しちゃってよ、みたいな場合は以下のように書けます。
@Test @UsingDataSet("dataset.xml") @Cleanup(phase= TestExecutionPhase.BEFORE,strategy= CleanupStrategy.STRICT) //テスト前に全部消しておく @ShouldMatchDataSet("expected_dataset.xml") public void データベースの更新テスト(){ MyMeibo myMeibo = meibo.find(0002); assertThat(myMeibo.getName(), is("makimaki")); //取得できるのはmakimakiだよね? //ID 0002のレコードの名前をmakimakiからmakiへ変更するよー myMeibo.setName("maki"); //更新してみるねー meibo.edit(meibo); }
ちなみにさきほどと同じように書くと
テーブルに元々入ってるデータ
| ID | NAME |
| 0000 | kikutaro |
テストで追加するデータ(@UsingDataSetアノテーションで入れるデータ)
| ID | NAME |
| 0001 | horikita |
| 0002 | makimaki |
テスト実行時(ID=0000のkikutaroが消されてからinsertされる)
| ID | NAME |
| 0001 | horikita |
| 0002 | makimaki |
テスト完了後
同上。
最後にデータが残る挙動となりますので、少しだけ注意が必要ですかね。
このあたりのCleanup設定についてはドキュメントで書いてあるので、実際に試しながらやるのが一番ですね。クエリとかも書けるみたいですが、とりあえずこれだけでも十分なような…。
JSFのFacesContext.getCurrentInstance()がnull
Arquillianを色々試していて、今日知ったのですが、テスト時にJSF周辺は
気を付ける必要があるということ。
自分がハマったのは、ログ出力のためにIPアドレスを取得する部分でFacesContext.getCurrentInstance()から色々引きずり出しているのですが、FacesContext.getCurrentInstance()自体がテスト時にnullとなることでした。
Arquillianテストコードのアーカイブする部分でfaces-config.xmlを入れていないからかな、と思ってやったのですが駄目でした orz
ググっていたら
などあって、そういうもののようです。
JSFUnitか…また僕にとっては新しいモノが出てきました(^^;頭が追い付かない。