Edited at

JUnitのアサーションライブラリHamcrest,AssertJ比較

More than 3 years have passed since last update.


なぜ今アサーション?

現時点でJUnit5ではHamcrestのMatcherは提供せず、使用者が自由に選択する方針で進んでいます。

そうなった場合、標準でサポートされるassertTrueやassertEquelsなどだけでは、ちょっと頼りなく車輪の再発明になりそうなので、候補になりそうなHamcrestとAssertJのよく使いそうなメソッド比較表を作りました。

Google Truthも気になるところなので、時間があれば追加しようと思います。

尚、FESTは現時点で更新がストップしているようなので候補から除外しています。


アサーションライブラリ


Hamcrest

Junit4で標準採用されているアサーションライブラリ。

知名度や採用実績では言うまでもなく一番だと思います。


Sample

public class HamcrestTest {

List<String> list = Arrays.asList("hoge", "fuga", "piyo");

@Test
public void test() {
assertThat(true, is(true));
assertThat("hoge", is("hoge"));
assertThat(list, is(not(empty())));
assertThat(list, is(contains("hoge", "fuga", "piyo")));
}

}



AssertJ

"Fluent assertions for java"と謳っているとおり、メソッドチェインでアサーション処理を記述できます。

またJava 8対応、外部ライブラリ連携、容易なカスタムアサーション生成など多くの機能にも対応しています。


Sample

public class AssertJTest {

List<String> list = Arrays.asList("hoge", "fuga", "piyo");

@Test
public void test() {
assertThat(true).isTrue();
assertThat("hoge").isEqualTo("hoge");
assertThat(list).isNotEmpty()
.contains("hoge", "fuga", "piyo");
}

}


見た目はHamcrestとあまり変わらないように感じますが、大きなメリットはFluent APIのため、チェック対象の型情報からIDE補完で使用可能なメソッド一覧を選択できることです。

このため、Hamcrestのように事前にAPIを把握していなくても、型安全性を維持したまま直感的にチェック処置が記述可能です。(例えば、isTrueはチェック対象がboolean、containsはコレクションや配列などの場合にのみ候補になる)


Truth

Google Guavaのテストコードなどにも使われているアサーションライブラリ。

直感的なエラーメッセージや、拡張性に違いはありますがAssertJやFESTから影響を受けているため非常に似たインターフェイスとなっています。


メソッド比較

機能
Hamcrest
AssertJ

チェック対象を指定する
assertThat
assertThat

Trueであることをチェックする
is
isTrue

Falseであることをチェックする
is
isFalse

同じ値であることをチェックする
is
isEqualTo

同じ値でないことをチェックする
is + not
isNotEqulTo

nullであることをチェックする
is + nullValue
isNull

nullでないことをチェックする
is + notNullValue
isNotNull

compareTo() で比較する
is + comparesEqualTo
isEqualByComparingTo

同じインスタンスであることをチェックする
is + sameInstance
isSameAs

指定したクラスのインスタンス型であることをチェックする
is + instanceOf
isInstanceOf

toString() で比較する
is + hasToString
hasToString

指定した文字で始まることをチェックする
is + startsWith
startsWith

指定した文字で終わることをチェックする
is + endsWith
endsWith

指定した文字が含まれることをチェックする
is + containsString
contains

大文字・小文字を区別せずに比較する
is + equalToIgnoringCase
isEqualToIgnoringCase

大文字・小文字・ブランク文字を無視して比較する
is + equalToIgnoringWhiteSpace
isEqualToIgnoringWhitespace

空文字であることをチェックする
isEmptyString
isEmpty

空文字または null であることをチェックする
isEmptyOrNullString
isNullOrEmpty

正規表現を使ってチェックする
-
matches

数値であることをチェックする
-
containsOnlyDigits

行数をチェックする
-
hasLineCount

指定した順序で文字列が現れることをチェックする
is + stringContainsInOrder
containsSequence

指定した範囲の値であることをチェックする
is + closeTo
isBetween

指定した値より大きいことをチェックする
is + greaterThan
isGreaterThan

指定した値以上であることをチェックする
is + greaterThanOrEqualTo
isGreaterThanOrEqualTo

指定した値より小さいことをチェックする
is + lessThan
isLessThan

指定した値以下であることをチェックする
is + lessThanOrEqualTo
isLessThanOrEqualTo

全ての要素が等しいことをチェックする
is + contains
contains

指定した要素を持つことをチェックする
hasItem
containsOnly

指定した要素を全て含むことをチェックする
hasItems
containsOnly

指定したサイズであることをチェックする
hasSize
hasSize

空であることをチェックする
is + empty
isEmpty

空の Iterator であることをチェックする
is + emptyIterable
isEmpty

指定したエントリを持つことをチェックする
hasEntry
containsEntry

指定したキーを持つことをチェックする
hasKey
containsKey

指定した値を持つことをチェックする
hasValue
containsValue

指定したプロパティを持つことをチェックする
hasProperty
filteredOn

全てのプロパティが等しいことをチェックする
is + samePropertyValuesAs
isEqualToComparingFieldByField

定した要素と配列の要素が全て等しいことをチェックする
is + arrayContaining
containsExactly

順序を無視して、指定した要素が全て配列に含まれることをチェックする
is + arrayContainingInAnyOrder
contains

配列のサイズをチェックする
is + arrayWithSize
hasSize

配列が空であることをチェックする
is + emptyArray
isEmpty

配列の中に指定した値が存在することをチェックする
hasItemInArray
contains

テストに失敗したときのメッセージを上書きする
describedAs
as


まとめ

個人的には、IDE補完が効くことや、コレクション、配列など同系統の処理のインターフェイスが統一されているなどAssertJの方が使いやすい印象です。

新規のライブラリは、その学習コストが問題になりがちですが、現状Hamcrestをバリバリ使いこなしているチームでないかぎり、AssertJはIDE補完から選択できるので、同様の機能が容易に使えます。

また、カスタムアサーションやJava 8対応、外部ライブラリ連携など柔軟性、機能性共に高いところも魅力です。

JUnit5からだけでなく、JUnit4からでも十分採用する価値はあると思います。


参考

HamcrestのMatchersに定義されているメソッドの使い方メモ

AssertJ版:テストでよく使う検証メソッド一覧