JUnit API探訪:Assertクラス/assertThatメソッド
JUnitをより深く知っていこう。と言う事で本丸JUnitのクラスから幾つか機能を探訪していこうかと思います。
org.junit.Assertクラス
主なメソッドは以下の通り。
メソッド | 説明 |
assertArrayEquals(arrays expected, arrays actual) | 配列同士を比較、イコールである場合true |
assertEquals(Object expected, Object actual) | オブジェクト同士を比較、イコールである場合true |
assertFalse(boolean condition) | 条件がfalseである事を検証、falseの場合true |
assertNotNull(Object obj) | オブジェクトがNullで無いことを検証、Nullでない場合true |
assertNotSame(Object expected, Object actual) | expected != actualの場合true |
assertNull(Object obj) | オブジェクトがNullである事を検証、Nullの場合true |
assertSame(Object expected, Object actual) | expected == actualの場合true |
assertTrue(boolean condition) | 条件がtrueである事を検証、trueの場合true |
assertThat([value], [matcher statement]) | 汎用的な比較を許可するアサーションメソッド |
fail() | 常に失敗させる。『ここに来たらアカン(テスト失敗)』箇所に配置 |
assertEqualsとassertSameについて、違いを調べてみる。
- Invention Works: JUnitのassertEquals(Object,Object)とassertSame(Object, Object)
- JUnit(DJUnit)について|半角全角な部屋
- JUnitの知識を棚卸し #JJUG - 日々常々
assertEqualsで事足りそうだし、assertSameを好んで使うという場面はそんなに無さげなのかな〜。
assertThatメソッド
Assertクラスのメソッドの1つ、assertThatメソッドについてはより範囲が広く、機能も多いので別途深掘り。assertThatに関しては以下のエントリ群が詳しいです。
- 【ハウツー】速攻解説! JUnit 4.4 - 新アサーションメソッド「assertThat」の用途とは | エンタープライズ | マイナビニュース
- JUnitの新しいアサーション assertThat - etc9
assertThatで使うMatcherに関しては、APIをざっと眺めるだけでても幾つか用意されているようです。
- org.hamcrest.CoreMatchers
allOf any anyOf anything describedAs equalsTo instanceOf is not notNullValue nullValue sameInstance
- org.junit.matchers.JUnitMatchers
both containsString either everyItem hasItem hasItems
org.hamcrest.Matchersのメソッド一覧
そしてこれらとは別にorg.hamcrest.Matchersというクラスも存在。これが一番提供メソッドも多いようなので今回はこちらのクラスメソッド群について色々写経しつつ、機能・概要を把握して行く事にする。(※このライブラリに関するJavadoc APIを見たほうが手っ取り早いと思ったんだけど、サイト経由では公開されてるJavadoc APIは確認出来ず。何でだろ?)
ざっくり用途・機能で分けつつ、写経したソースコードも一緒にUPしときます。振り分け的に怪しいのもあるかもしれないけどそこは御容赦を。
参考:
条件制御
allOf | すべてのMatcher条件が一致するかどうか |
anyOf | いずれかのMatcher条件が一致するかどうか |
anything | 何にでもマッチする |
both | AND条件を構成 |
either | OR条件を構成 |
describedAs | 検証条件の詳細を記述 |
is | 条件(である) |
not | 条件(でない) |
- allOf:全てのMatcher条件が一致するかどうかを検証
@Test public void checkAllOf() { // 全てのMatcher条件が一致していればOK assertThat( "HelloWorld", allOf( is("HelloWorld"), notNullValue(), startsWith("Hello") ) ); }
- anyOf:いずれかのMatcher条件が一致していればOK
@Test public void checkAnyOf() { // いずれかのMatcher条件が一致していればOK assertThat( "HelloWorld", anyOf( is("HelloWorld!!!"), nullValue(), startsWith("Hello") ) ); }
- anything:何にでも一致
@Test public void checkAnything() { // 何でも一致 assertThat("Java", anything()); }
- both:AND条件を構成
- either:OR条件を構成
@Test public void checkBothAndEither() { // both A and B assertThat("java", both(startsWith("j")).and(endsWith("a"))); // either A or B assertThat("java", either(startsWith("j")).or(startsWith("g"))); }
- describedAs:検証条件の詳細を記述
@Test public void checkDescribedAs() { // 一致しない場合、"Expected: start with J but: was "XXXX"となる String text = "Java"; assertThat(text, describedAs("start with J", startsWith("J"))); }
- is:条件(である)
- not:条件(でない)
// この後のコードで沢山出てくるのでここでのコードは割愛
オブジェクト・型検証に関するもの
any | 引数に取った型のクラスなら何でも良い、という指定を行う場合に使う(※instanceofのエイリアス) |
equalTo | 比較(一致していること) |
instanceOf | オブジェクトの型を検証 |
isA | 型のマッチング検証に用いる |
notNullValue | 条件(Nullではない) |
nullValue | 条件(Nullである) |
sameInstance | インスタンスの同一性を検証 |
- any:引数に取った型のクラスなら何でも良い、という指定を行う場合に使う(※instanceofのエイリアス)
@Test public void checkAny() { // any は instanceof のエイリアス。クラス型が合ってれば良い assertThat("Java", is(any(String.class))); assertThat(1, is(any(Integer.class))); assertThat(10, is(any(Object.class))); }
- equalTo:比較(一致していること)
// 比較 assertThat(100, equalTo(100)); assertThat("foo", equalTo("foo")); assertThat(new String[] {"foo", "bar"}, equalTo(new String[] {"foo", "bar"}));
- instanceOf:オブジェクトの型を検証
@Test public void checkInstanceof() { // インスタンスの型を確認 assertThat("Java", is(instanceOf(String.class))); }
- isA:型のマッチング検証に用いる
@Test public void checkISA() { // 型のマッチング検証 assertThat(new Date(), isA(Date.class)); assertThat("java", is(any(String.class))); assertThat(10000, is(instanceOf(Integer.class))); }
- notNullValue:Nullではない
- nullValue:Nullである
assertThat("java", notNullvalue); assertThat(null, nullvalue);
- sameInstance:インスタンスの同一性を検証
@Test public void checkSameInstance() { // インスタンスの同一性を検証 Boolean flag = false; assertThat(flag, sameInstance(Boolean.FALSE)); String text = "string"; assertThat(text, sameInstance("string")); }
文字列検証に関するもの
containsString | 文字要素を含むかどうかを検証 |
endsWith | 指定の文字列で終わっていることを検証 |
equalToIgnoringCase | 比較(文字列:大文字小文字の違いを無視) |
equalToIgnoringWhiteSpace | 比較(文字列:大文字小文字の違い、更には空白文字も無視) |
hasToString | toStringの内容を明示的に比較 |
isEmptyOrNullString | 文字列が空もしくはNullである事を検証 |
isEmptyString | 文字列が空である事を検証 |
startsWith | 指定の文字列で始まっている事を検証 |
stringContainsInOrder | 文字列の中に文字列(配列要素)が含まれているかどうかを検証 |
- containsString : 文字要素を含むかどうかを検証
// 指定した文字列を含んでいるか assertThat("この先生きのこるために", is(containsString("きのこ")));
- startsWith:指定の文字列で始まっている事を検証
- endsWith:指定の文字列で終わっていることを検証
assertThat("java", both(startsWith("j")).and(endsWith("a"))); assertThat("java", either(startsWith("j")).or(startsWith("g")));
- equalToIgnoringCase:比較(文字列:大文字小文字の違いを無視)
- equalToIgnoringWhiteSpace:比較(文字列:大文字小文字の違い、更には空白文字も無視)
// 比較(大文字小文字の違いを無視) assertThat("JUNITTESTCASE", is(equalToIgnoringCase("JUnitTestCase"))); // 比較(大文字小文字の違い・前後の空白(半角・全角)を無視 assertThat(" JAVASCRIPT ", is(equalToIgnoringWhiteSpace("Javascript"))); // 比較(間にある空白は無視してくれないらしい) assertThat(" JAVA SCRIPT ", is(not(equalToIgnoringWhiteSpace("Javascript"))));
- hasToString:toStringの内容を明示的に比較
// toStringの内容を明示的に比較検証 List<Integer> list = new ArrayList<Integer>(); list.add(111); list.add(222); list.add(333); assertThat(list.toString(), is(hasToString("[111, 222, 333]"))); assertThat(new Object(), is(hasToString(startsWith("java.lang.Object@"))));
- isEmptyOrNullString:文字列が空もしくはNullである事を検証
// 文字列が空もしくはNullである事を確認 String nullString = null; assertThat(nullString, isEmptyOrNullString()); String emptyString = ""; assertThat(nullString, isEmptyOrNullString());
- isEmptyString:文字列が空である事を検証
// 文字列が空である事を確認
assertThat(emptyString, isEmptyString());
assertThat(nullString, not(isEmptyString()));
- stringContainsInOrder:文字列の中に文字列(配列要素)が含まれているかどうかを検証
// assertThat("myfoobarbaz", stringContainsInOrder(Arrays.asList("bar", "foo"))) // 文字列の中に文字列群が存在するかを確認(所定の順番で存在している必要がある) assertThat("myfoobarbaz", stringContainsInOrder(Arrays.asList("foo", "bar"))); assertThat("myfoobarbaz", not(stringContainsInOrder(Arrays.asList("bar", "foo")))); assertThat("myfoobarbaz", stringContainsInOrder(Arrays.asList("myfoo", "foobar"))); assertThat("myfoobarbaz", stringContainsInOrder(Arrays.asList("foobar", "foobar"))); assertThat("myfoobarbaz", not(stringContainsInOrder(Arrays.asList("foobar", "yfoob"))));
数値検証に関するもの
closeTo | 数値期待値の検証 |
comparesEqualsTo | 数値比較(同値) |
greaterThan | 数値比較(より大きい) |
greaterThanOrEqualTo | 数値比較(以上) |
lessThan | 数値比較(未満) |
lessThanOrEqualTo | 数値比較(以下) |
- closeTo :数値期待値の検証
// 期待値の範囲内かどうかを検証 assertThat(10.2, is(closeTo(10, 0.3)));
- comparesEqualsTo:数値比較(同値)
// 数値比較(equal) assertThat(new BigDecimal("1000"), comparesEqualTo(new BigDecimal(1000)));
- greaterThan:数値比較(より大きい)
- greaterThanOrEqualTo:数値比較(以上)
// 数値比較(greaterThan) assertThat(10, is(greaterThan(9))); assertThat(10, is(greaterThanOrEqualTo(10))); assertThat(10, is(greaterThanOrEqualTo(9)));
- lessThan:数値比較(未満)
- lessThanOrEqualTo:数値比較(以下)
// 数値比較(lessThan) assertThat(100.02, is(lessThan(101.03))); assertThat(100, is(lessThanOrEqualTo(101))); assertThat(100, is(lessThanOrEqualTo(100)));
配列検証に関するもの
array | 配列要素を比較、検証する際に構成要素として用いる |
arrayContaining | 配列内容・順序が一致しているかどうか |
arrayContainingInAnyOrder | 配列内容が一致しているかどうか(順序は問わない) |
arrayWithSize | 配列のサイズを確認 |
emptyArray | 配列要素が空である事を検証 |
hasItemInArray | 配列内に所定の要素を含むかどうか確認 |
- array:配列要素を比較、検証する際に構成要素として用いる
@Test public void checkArray() { // 配列要素を比較、検証する際に構成要素として用いる。 // 値が異なる場合、配列要素インデックス及び異なった値がbutの詳細情報として表示される assertThat( new String[]{"Java", "Groovy", "Scala"}, is(array( is("Java"), is(startsWith("G")), notNullValue() ))); }
- arrayContaining:配列内容・順序が一致しているかどうか
- arrayContainingInAnyOrder:配列内容が一致しているかどうか(順序は問わない)
- arrayWithSize:配列のサイズを確認
@Test public void checkArrayContaining() { String[] actual = {"100", "200", "300", "400"}; // arrayContaining: 配列の内容・順序が一致しているかどうか assertThat(actual, arrayContaining("100", "200", "300", "400")); // arrayContainingInAnyOrder: 配列の内容が一致しているかどうか(順序は問わない) assertThat(actual, arrayContainingInAnyOrder("400", "100", "300", "200")); // arrayWithSize: 配列のサイズを確認 assertThat(actual, arrayWithSize(4)); assertThat(actual, not(arrayWithSize(5))); }
- emptyArray:配列要素が空である事を検証
// 配列要素が空である事を確認 String[] actualStringArray = new String[0]; assertThat(actualStringArray, is(emptyArray())); String[] actualStringArray2 = new String[3]; assertThat(actualStringArray2, is(not(emptyArray())));
- hasItemInArray :配列内に所定の要素を含むかどうか確認
// 配列内に所定の要素を含むかどうか確認 String[] stringsArray = {"scrum", "agile", "xp"}; assertThat(stringsArray, hasItemInArray("agile"));
コレクション検証に関するもの
contains | コレクション要素が指定通りの順番で一致しているか検証 |
containsInAnyOrder | コレクション要素が一致しているかを検証(順番は問わない) |
empty | コレクション要素が空であることを検証 |
emptyCollectionOf | 所定の型で構成された空のコレクションで有ることを検証 |
emptyIterable | コレクションから得られるiteratorが空である事を検証 |
emptyIterableOf | iteratorの型を確認しつつ、空である事を検証 |
hasItem | コレクション内に所定の要素を含むかどうか検証 |
hasItems | コレクション内に所定の要素(複数指定可能)を含むかどうか検証 |
hasSize | コレクションのサイズを検証 |
isIn | コレクションに所定の要素を含むかどうか検証 |
isOneOf | コレクションに所定の要素を含むかどうか検証 |
iterableWithSize | サイズを検証 |
- contains:コレクション要素が指定通りの順番で一致しているか検証
- containsInAnyOrder:コレクション要素が一致しているかを検証(順番は問わない)
List<String> actual = new ArrayList<>(); actual.add("Java"); actual.add("Groovy"); actual.add("Scala"); // 指定の順番通りにコレクション要素が一致しているか String[] expected = {"Java","Groovy","Scala"}; assertThat(actual, is(contains(expected))); // コレクション要素が一致しているか(順番は問わない) String[] expectedInAnyOrder = {"Groovy","Scala","Java"}; assertThat(actual, is(containsInAnyOrder(expectedInAnyOrder)));
- empty:コレクション要素が空であることを検証
@Test public void checkEmptyCondition() { // コレクション要素が空である事を検証 List<Integer> actual = new ArrayList<Integer>(); assertThat(actual, is(empty())); actual.add(10); assertThat(actual, not(empty())); }
- emptyCollectionOf:所定の型で構成された空のコレクションで有ることを検証
- emptyIterable:コレクションから得られるiteratorが空である事を検証
- emptyIterableOf:iteratorの型を確認しつつ、空である事を検証
//assertThat(new ArrayList<String>(), is(emptyCollectionOf(String.class))) // 所定の型で構成された空のコレクションで有ることを検証 List<BigDecimal> actualList = new ArrayList<BigDecimal>(); assertThat(actualList, is(emptyCollectionOf(BigDecimal.class))); // assertThat(new ArrayList<String>(), is(emptyIterable())) // コレクションから得られるIteratorが空である事を確認 assertThat(actualList, is(emptyIterable())); List<String> stringList = new ArrayList<String>(); assertThat(stringList, is(emptyIterable())); // Iteratorの型を確認しつつ、空である事を確認 assertThat(actualList, is(emptyIterableOf(BigDecimal.class))); assertThat(stringList, is(emptyIterableOf(String.class)));
- hasItem:コレクション内に所定の要素を含むかどうか検証
- hasItems:コレクション内に所定の要素(複数指定可能)を含むかどうか検証
- hasSize:コレクションのサイズを検証
- isIn:コレクションに所定の要素を含むかどうか検証
- isOneOf:コレクションに所定の要素を含むかどうか検証
// コレクション内に所定の要素を含むかどうか確認 List<String> stringList = new ArrayList<String>(); stringList.add("perl"); stringList.add("php"); stringList.add("python"); assertThat(stringList, hasItem("php")); assertThat(stringList, hasItems("perl", "python")); assertThat(stringList, hasItems("perl")); // コレクションのサイズを検証 assertThat(stringList, hasSize(3)); // コレクション内に要素を含むかどうか確認 assertThat("php", isIn(stringList)); assertThat("php", isOneOf("php", "perl", "python"));
Map検証に関するもの
hasEntry | Mapオブジェクトに所定のkey-valueエントリが含まれているかを検証 |
hasKey | Mapオブジェクトに所定のkeyが含まれているかを検証 |
hasValue | Mapオブジェクトに所定のvalueが含まれているかを検証 |
@Test public void checkMaps() { Map<Integer, String> actualMap = new HashMap<Integer, String>(); actualMap.put(1, "Java"); actualMap.put(2, "Groovy"); actualMap.put(3, "Scala"); assertThat(actualMap, hasEntry(2, "Groovy")); assertThat(actualMap, hasKey(3)); assertThat(actualMap, hasValue("Java")); }
Bean要素検証に関するもの
hasProperty | Bean要素に所定のプロパティが存在するかどうかを検証 |
samePropertyValuesAs | Beanのプロパティ値の内容を検証 |
public class Person { private String name; private int age; private String address; // setter, getterは割愛
// Bean要素に所定のプロパティが存在するか確認 Person person = new Person(); assertThat(person, hasProperty("name")); assertThat(person, hasProperty("age")); assertThat(person, hasProperty("address")); assertThat(person, not(hasProperty("mail"))); // プロパティの値を比較 Person personActual = new Person(); personActual.setName("すずきいちろう"); personActual.setAge(39); personActual.setAddress("N.Y"); Person personExpected = new Person(); personExpected.setName("すずきいちろう"); personExpected.setAge(38); personExpected.setAddress("N.Y"); assertThat(personActual, is(samePropertyValuesAs(personExpected)));
その他
その他上記で分類しきれなかったものなどを列挙。まぁ力尽きたとも言うが…w いずれ対応出来れば。
eventFrom | Eventオブジェクト関連のメソッド |
eventItem | Eventオブジェクト関連のメソッド |
hasXPath | XMLドキュメントの検証用 |
theInstance | |
typeCompatibleWith |
ふぅ…これだけ量があると概要把握するだけでも時間掛かりますわな。でもassertThatメソッド、これだけ機能が豊富で表現も豊かであれば、だいぶ便利に使えますな。引き続きJUnit APIについては興味深いところから学んで行こうと思います。
【追記】:このエントリを受けて、いろふさんが新たにエントリを書いてくれていた。やっぱりJavadoc無かったのか〜。その他諸々も勉強になります。