のついでに hamcrest の CoreMatchers についてまとめます。
Matchers については
blog1.mammb.com
まずは基本の is と not
全体的にはこんな感じ。
import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import org.junit.Test; public class FooTest { @Test public void testFoo() { String actual = "foo"; assertThat(actual, is("foo")); } }
not はこう。
String actual = "foo"; assertThat(actual, not("bar")); assertThat(actual, is(not("bar")));
equalTo と is
is は equalTo の構文糖であるため、以下は全て等価です。
assertThat(actual, equalTo(expected)); assertThat(actual, is(equalTo(expected))); assertThat(actual, is(expected));
英語として読み下し易くするために、is に matcher を渡すのが普通です。
インスタンスに関する検証
is(や equalTo)は Object.equals によるオブジェクトの同一性を検証しますが、インスタンスの同一性の検証には sameInstance が用意されています。
List<String> actual = Arrays.asList("foo","bar"); assertThat(actual, is(sameInstance(Arrays.asList("foo","bar")))); // Assertion Error List<String> expected = actual; assertThat(actual, is(sameInstance(expected))); // OK
instanceOf は型の互換性を検証します。
List<String> actual = Arrays.asList("foo","bar"); assertThat(actual, is(instanceOf((Collection.class))));
null値の検証
null値の検証には nullValue と notNullValue があります
String actual = null; assertThat(actual, is(nullValue())); String actual = "hoge"; assertThat(actual, is(notNullValue()));
常にマッチするanything
anything は常にマッチします。テストにてどんな値でも気にしないことを明示する場合に使用できます。
assertThat(actual, is(anything()));
assertThat(actual, is(anything("always matches")));
Assertion Error 時出力を変更する
describedAs を使うと、Assertion Error 時説明をカスタマイズして設定できます。
assertThat("foo", describedAs("foo is not foo1", is("foo")));
この例だと、検証失敗時に「foo is not foo1」の説明を得ることができます。
また、describedAs にはバインド文字列を指定できます。以下のようにすると、
assertThat("foo1", describedAs("foo is not %0", is("foo"), "[foo]"));
Assertion Error の出力は「Expected: foo is not "[foo]"」のように出力されます。
文字列の検証
Hamcrest 1.2 より containsString、startsWith、endsWith といった文字列用の Matcher が追加されました(org.junit.matchers.JUnitMatchers からマージされた)。
String actual = "foobar"; assertThat(actual, is(containsString("ooba"))); assertThat(actual, is(startsWith("foo"))); assertThat(actual, is(endsWith("bar")));
allOf と anyOf
Matcher を AND で検証する allOf
String actual = "foobar"; assertThat(actual, is(allOf(startsWith("fo"), endsWith("ar"))));
Matcher を OR で検証する anyOf
String actual = "foobar"; assertThat(actual, is(anyOf(startsWith("foo"), startsWith("bar"))));
Hamcrest 1.2 で CoreMatchers に追加されたものたち
both と either
String actual = "foobar"; assertThat(actual, both(containsString("a")).or(containsString("c"))); assertThat(actual, both(containsString("a")).and(containsString("b"))); assertThat(actual, both(containsString("a")).and(containsString("c"))); // NG
either も同様です。
コレクション系の everyItem、hasItem、hasItems
Collection<String> actual = Arrays.asList("foo1", "foo2", "foo3"); assertThat(actual, is(everyItem(startsWith("foo"))));
Collection<String> actual = Arrays.asList("foo1", "foo2", "foo3"); assertThat(actual, is(hasItem("foo2")));
Collection<String> actual = Arrays.asList("foo1", "foo2", "foo3"); assertThat(actual, is(hasItems("foo2", "foo3")));
Hamcrest 1.3 で CoreMatchers に追加されたものたち
any と isA が追加されています。いずれも instanceOf のショートカットだと思う・・
assertThat("foo", isA(String.class)); assertThat(10, isA(Number.class));
assertThat("foo", is(any(String.class))); assertThat(10, is(any(Number.class)));