JUnitが出始めのころに使い方を覚えた人は、
assertEquals()やassertTrue()などの方がなじみがある。
しかし、最近はassertThat()を使う方が普通で便利。

assertThat()はJUnit4.4(2007年リリース)から追加された。
JUnit4.4のリリースから5年以上たって、情報も増えてきた。
そろそろassertEquals()は卒業したい。

Maven
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-all</artifactId>
  <version>1.3</version>
  <scope>test</scope>
</dependency>

equals()を検証に用いると不便なことがある

assertEquals()では
「equals()」あるいは「==」を利用した検証になる。

assertEquals()を用いたテスト
String expected = "Hello World";
String actual = "Hello" + " " + "World";
assertEquals(expected, actual);

基本的には問題ない。
これまでこれでやってこられた。

ただ、この「equals()」を利用していることが問題になる。

オブジェクトにequals()は一つしか作れない。
equals()に定義してある内容(状況)と
違う検証をしようとするときに困ってしまう。

これを回避しようと
assertEquals()をフィールドの数分
書いたりする事態になったりするので
やはり困ってしまう。

そもそも「equals()」を必ずしも
定義するとも限らない。

というわけで、なんとなくassertEquals()を使っていたかもしれないが
不便なところ(改善点)も存在する。

検証処理をMatcherとして分離する

先ほどの「equals()」の問題に対処できる
assertThat()とMatcherの組み合わせがJUnit4.4から登場する。

クラス図とコードは次のようになる。

JUnit_クラス図
assertThat()とMatcherを用いたテスト
String expected = "Hello World";
String actual = "Hello" + " " + "World";
assertThat(actual, is(expected));

一見するとあまり変わったように見えない。
actualとexpectedが逆になったぐらい。

ただ、重要なのはassertThat自体は検証処理をしていなくて、
Matcherオブジェクト検証処理を行っていること。
(is()というのはCoreMachersクラスのメソッドでMacherのファクトリ)

このように検証処理をMatcherに分離することで
Matcherを作ってしまえば、オブジェクトのequals()の内容にかかわらず
検証することができるという仕組み。

これによりequals()の問題を回避できる。
(もちろんeauals()を用いた検証も可能)

そして、検証メソッドはassertThatに固定されるので
assertEqualsを何個も何個もという事態も
もちろんなくなる。

この他にも、次のようなメリットがある。

  • 自然な可読
  • 詳細なエラーメッセージ

このようにassertThatとMatcherの方が
assertEquals()より手広くてメリットも多いので
切り替えるべき。

汎用的なMatcherはもちろん提供される

検証処理がMatcherオブジェクトに任されるようになったので
毎回Matcherを作るのかといえば、そんなことにはならない。

汎用的なものはファクトリメソッドで提供されている。

Matcherクラス図

Matcher API はもともとHamcrestというライブラリのものだった。
メジャーなものはバージョン4.4から本家に組み込まれたので
JUnitが利用できるなら使える。

少々マイナーなMatcherもHamcrestのライブラリを
プロジェクトに組み込めば利用できる。

ほかにもサードパーティから提供されるものも存在する。

このように汎用的なものはライブラリに任せて
プロジェクト独自のものは必要なときだけ
Matcherを自作する。

まずはCoreMatchersを使えるようにする

assertThatとMatcherの入りとしては
CoreMatchersに慣れること。

is(),not(),nullValue(),sameInstance()あたりが
使えればよい。

難しいことはないので
スタイルに慣れることが重要。

特にis()がわかればassertEquals()と同等のことは可能なので
スタートはそこから。

これまでassertEquals()で書こうとしたところを
assertThat(actual,is(expected))というように書くことから始めよう。

PR