assertEquals()は古い。assertThat()+Matcherを使う。
assertEquals()の方になじみがある方も多いかも知れないが、assertThat()を使う方が便利。そろそろassertEquals()は卒業したい。
assertEquals()の限界
assertEquals()では「equals()」あるいは「==」を利用した検証になる。
String expected = "Hello World";
String actual = "Hello" + " " + "World";
assertEquals(expected, actual);
基本的には問題ない。これでもやっていける。ただこの「equals()」に頼っていることが問題になる。
オブジェクトにequals()は一つしか作れない。equals()に定義してある内容(状況)と違う検証をしようとするときに困ってしまう。これを回避しようとするとフィールドの数分assertEquals()を書いたりする事態になったりするのでうれしくない。そもそも「equals()」を必ずしも定義するとも限らない。
というわけで、なんとなくassertEquals()を使ってきたかもしれないが不便なところ(改善点)も存在する。
検証処理をMatcherとして分離する
assertEquals()の限界に対処するassertThat()とMatcherの仕組みがJUnit4.4から登場する。

String expected = "Hello World";
String actual = "Hello" + " " + "World";
assertThat(actual, is(expected));
一見するとあまり変わったように見えない。actualとexpectedが逆になったぐらい。
重要なのはassertThat自体は検証処理をしていなくて、Matcherオブジェクト検証処理を行っていること。(is()というのはCoreMachersクラスのメソッドでMacherのファクトリ)
このように検証処理をMatcherに分離することで、Matcherを作ってしまえばオブジェクトのequals()の内容にかかわらず検証することができるという仕組み。これによりequals()の問題を回避できる。(もちろんeauals()を用いた検証するMatcherもある)
そして、検証メソッドはassertThatに固定されるのでassertEqualsを何個も何個もという事態ももちろんなくなる。この他にも、次のようなメリットがある。
-
自然な可読
-
詳細なエラーメッセージ
このようにassertThatとMatcherの方が、assertEquals()より手広くなりメリットも多いので切り替えるべき。
まずはCoreMatchersを使えるようにする
検証処理がMatcherオブジェクトに任されるようになったので、毎回Matcherを作るのかといえばそんなことにはならない。汎用的なものはCoreMatchersやMatchersクラスのファクトリで提供される。少し特別な検証をしたいときだけ自作する。

Matcher API はもともとHamcrestというライブラリのものだった。 メジャーなものはバージョン4.4から本家に組み込まれたのでJUnitが利用できるなら設定なしで仕様できる。
assertThatとMatcherの入りとしてはCoreMatchersに慣れること。is(),not(),nullValue(),sameInstance()あたりが使えればよい。難しいことはないのでスタイルに慣れることが重要。
特にis()がわかればassertEquals()と同等のことは可能なのでスタートはそこから。
Appendix A: 参考
Appendix B: 改訂履歴
-
v1.0, 2017-04-12: 初稿