JUnit 実践入門 体系的に学ぶユニットテストの技法 - 第4章 アサーション 値を比較検証するしくみ
第4章 アサーション 値を比較検証するしくみ
4.1 Assert による値の比較検証
- org.junit.Asset にアサーションメソッドが多数定義されている
- static インポートされることを想定した static メソッド
- assertThat と fail 2つ知っていれば十分。
assertThat - 汎用的な値の比較検証
- JUnit では、比較のルールと比較検証のしくみを分離している
- ルール: Matcher オブジェクト。場合によってカスタマイズも出来る
- しくみ: assertThat メソッド。仕組み自体はそのまま使いまわしていける。
fail - テストを失敗させる
4.2 Matcher API によるアサーションの特徴
- Matcher API は Hamcrest という、JUnit の独立した拡張ライブラリの一つだったが、統合された
- 以前は assertEquals メソッドに比較ルールを実装していたが、柔軟性や可読性に欠けた
- 可読性の高い記述
- 柔軟な比較
- 詳細な情報の提供
4.3 Matcher API の利用
- org.hamcrestCoreMatchers クラスや、org.junit.matchers.JUnitMatchers クラスなどに定義された、static なファクトリメソッドから Matchers オブジェクトを生成する。
- static インポートはワイルドカード指定が便利
CoreMatchers が提供する Matcher
- is
- 独自実装クラスのオブジェクトに対して利用する場合は、適切な equals メソッドがオーバーライドされているか要確認。基本はデフォルト equals が使われるため、予期しない結果になるかも。
- nullValue
- not
- notNullValue
- sameInstance
- instanceOf
- 実測値が null の場合は必ず失敗
JUnitMatchers が提供する Matcher
- hasItem
- hasItems
カスタム Matcher の作成
- 日付をざっくり比較する(ミリ秒とかいらない) Matcher をつくる
手順
isDate クラスの作成
- BaseMtcher クラスを extends
ファクトリメソッド作成
- static インポートにより、自然言語に近い形で表記したいため
- プロジェクトで複数のカスタム Matcher 作るなら、ファクトリメソッドをまとめて定義したクラスを作成すると吉
コンストラクタの定義
matches メソッドの実装
- 実測値を引数に取り、一致なら true、そうでなければ false を返す
- 一致しない場合には、describeTo メソッドが呼び出される
discribeTo メソッドの実装
- フレームワークに比較検証が失敗した理由を通知する
テスト失敗メッセージの確認
- ここを見て原因がすぐに分かるよう、describeTo を工夫する
ソースコード
プロダクションコード
package ch04; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; public class IsDate extends BaseMatcher{ private final int yyyy; private int mm; private int dd; Object actual; IsDate(int yyyy, int mm, int dd) { this.yyyy = yyyy; this.mm = mm; this.dd = dd; } @Override public boolean matches(Object actual) { this.actual = actual; if (!(actual instanceof Date)) return false; Calendar cal = Calendar.getInstance(); cal.setTime((Date) actual); if (yyyy != cal.get(Calendar.YEAR)) return false; if (mm != cal.get(Calendar.MONTH) + 1) return false; if (yyyy != cal.get(Calendar.DATE)) return false; return true; } @Override public void describeTo(Description desc) { desc.appendValue(String.format("%d/%02d/%02d", yyyy, mm, dd)); if (actual != null) { desc.appendText(" but actual is )"); desc.appendValue(new SimpleDateFormat("yyyy/MM/dd").format((Date) actual)); } } public static Matcher dateOf(int yyyy, int mm, int dd) { return new IsDate(yyyy, mm, dd); } }
テストコード
package ch04; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static ch04.IsDate.*; import java.util.Date; import org.junit.Test; public class IsDateTest { @Test public void 日付の比較() { assertThat(new Date(), is(dateOf(2012, 1, 12))); } }

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)
- 作者: 渡辺修司
- 出版社/メーカー: 技術評論社
- 発売日: 2012/11/21
- メディア: 単行本(ソフトカバー)
- 購入: 14人 クリック: 273回
- この商品を含むブログ (65件) を見る