2015-12-27 『JUnit実践入門』読書会(第4章)の振り返り
JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)
- 作者: 渡辺修司
- 出版社/メーカー: 技術評論社
- 発売日: 2012/11/21
- メディア: 単行本(ソフトカバー)
- 購入: 14人 クリック: 273回
- この商品を含むブログ (68件) を見る
第4章 アサーション
assertThatメソッド
- 値の比較検証のほとんどを行う
- 第1引数=実測値
- 第2引数=期待値との比較を行うMatcherオブジェクト
- 比較検証で値が一致しない場合、AssertionErrorが発生する
コメント
- assertThatかJUnit3までのassertXXXのほうが好みかは人によって分かれるもよう
→ assertThatだと途中でis
とか入れたくない
→ 旧メソッドの期待値を第1引数に入れるのが好きではない
などなど
failメソッド
- 無条件にテストを失敗させるメソッド
- テストを実装していないことを明らかにしたい場合に使われる
- あるブロックが実行されないことをテストしたい場合に使われる
Matcher API
- 何かの値に対して等価かを柔軟に比較するためのライブラリ
- ユニットテストのほとんどは等価かの比較
- 要素を含むか(hasItems)などの比較方法も提供し、一貫した書式でテストの意図を伝えやすい
→assertTrue(actual.contains(expected))
だとactualにexpectedを含むテストなのか、containsメソッドの意味なのかわかりにくい
→ hasItemメソッドは内部でcontains使ってる?
→ forループを使ってる
IsCollectionContaining.java
protected boolean matchesSafely( Iterable<? super T> collection, Description mismatchDescription) { boolean isPastFirst = false; for (Object item : collection) { if (this.elementMatcher.matches(item)) { return true; } if (isPastFirst) { mismatchDescription.appendText(", "); } this.elementMatcher.describeMismatch(item, mismatchDescription); isPastFirst = true; } return false;
- カスタムMatcherの作成が可能
- Matcher APIを使用するにはワイルドカードを使ったstaticインポートが楽
→ Eclipseではワイルドカードを使ったstaticインポートするのに設定の変更が必要
コメント
- assertEqualsメソッドだと、どのフィールドが一致しないかの詳細な情報が伝わらない?
→ カスタムのMatcher APIを使わなくてもassertEqualsメソッドだけでも実装次第でできるのでメリットを感じられない?
→ 単にassertEqualsメソッドでもフィールド単位で較すればいいだけでは? - オブジェクトにequalsメソッドをきちんと実装してテストを行うのは問題?
→ あとでフィールドが追加された際にテスト実装するときにオブジェクトのequalsメソッド修正時に実装漏れに気づく?
→ フィールドが追加された場合に、実装がプロダクションでもテストでも抜けてしまっった場合、どっちにしろテストは失敗しないので気づかれないのでは?
CoreMathers
is
nullValue
assertThat(astual, is(nullValue()));
not
assertThat(actual, is(not(0)));
notNullValue
assertThat(actual, is(notNullValue()));
これは下記と同じ
assertThat(actual, is(not(nullValue())));
sameInstance
- 値の比較ではなく同じインスタンスかの比較
- equalsではなく
==
の比較 - 基本データ型はボクシング変換されるので使うべきではない
instanceOf
- 実測値(actual)が比較するクラスと同じクラスもしくは比較クラスを継承したクラスならtrue
- 実測値(actual)がnulの場合は失敗になる
JUnitMathers
hasItem
- 実測値に期待値が含まれているか判定する
- 実測値は配列やIterableのオブジェクト
hasItems
カスタムMatcherの作成
日付の比較を行うカスタムMathcerの作成
次の要件を満たすカスタムMatcherを作る
- 年月日をそれおぞれintで指定して比較できる
- 時分秒は無視する
- 失敗したらyyyy/mm/dd表記で確認できるようにする
手順
独自Matcherクラスの生成
org.hamcrest.baseMathcerを継承する
- matchesメソッドとdescribeToメソッドを実装する
- matchesメソッドは比較検証を行う
describeToメソッドは失敗時の情報を作成する
ファクトリメソッドを作成する
Matcherを使いやすくするためstaticなファクトリメソッドを用意する
Matchesメソッドを実装する
boolean値で結果を返すmatchesメソッドを実装する
describeToメソッドを実装する
matchesメソッドがfalseの際に呼び出される
- 引数のDescriptionインスタンスに情報を追加する
- appendText:文字列を追加するメソッド
- appendValue:値を追加するメソッド。出力時に「"」で囲まれる
- 本のフォーマットと違い4.12だと実測値が
but: was
になっている - Descriptionに追加した情報は
Expected is
に表示される
テスト失敗時のメッセージ
Expected is "2000/01/01" but actual is "2015/12/27" but was <Sun Dec …略>
- 期待値にエラー情報含めて出すのに抵抗ある
→ メソッドが実績値、期待値含めたメッセージがつくれない点が微妙
→ 期待値にエラー情報含めて出すのはメッセージとして破たんしている - そもそも標準で用意されているメッセージ自体も実績値と期待値のインデントをそろえて出力したい(長文の文字列比較などやりやすいように)