JUnitのアサートの悩み
JUnitのアサートは基本的にisを使えば事足りますが、JavaBeanやListをアサートする場合に悩みます。
JavaBeanのプロパティやListの要素を1つずつアサートするのは面倒ですが、カスタムマッチャーを作るのも面倒だったり・作るほどでもない場合があります。
そうした場合にどうすべきか考えてみました。
isの注意点
org.hamcrest.CoreMatchers.is()は対象クラスのequalsメソッドでアサートを行います。
そのクラスがequalsメソッドをオーバーライドしていない場合、デフォルトのequalsメソッド、つまり、インスタンスの同一性をアサートします。
public class SampleBeanTest { @Test public void test() { SampleBean actual = new SampleBean("test"); SampleBean expected = new SampleBean("test"); assertThat(actual, is(expected)); // AssertionError } public class SampleBean { private String str; public SampleBean(String str) { this.str = str; } public String getStr() { return str; } } }
JavaBeanのアサート
org.hamcrest.Matchers.samePropertyValuesAs()を使えばJavaBeanごとアサートできます。
上記のサンプルコードはsamePropertyValuesAsを使えばアサートが成功します。
public class SampleBeanTest { @Test public void test() { SampleBean actual = new SampleBean("test"); SampleBean expected = new SampleBean("test"); assertThat(actual, is(samePropertyValuesAs(expected))); // OK } }
ただし、プロパティがJavaBeanの場合はインスタンスの同一性がアサートされるので注意が必要です。
@Test public void test() { SampleBean actual = new SampleBean("test", new SampleBean2("test2")); SampleBean expected = new SampleBean("test", new SampleBean2("test2")); assertThat(actual, is(samePropertyValuesAs(expected))); // AssertionError } public class SampleBean { private String str; private SampleBean2 sampleBean2; public SampleBean(String str, SampleBean2 sampleBean2) { this.str = str; this.sampleBean2 = sampleBean2; } public String getStr() { return str; } public SampleBean2 getSampleBean2() { return sampleBean2; } } public class SampleBean2 { private String str; public SampleBean2(String str) { this.str = str; } public String getStr() { return str; } } }
参考
JUnit4 で JavaBeans の assertThat を簡潔に書きたい
List(Stringとラッパークラス)のアサート
org.hamcrest.Matchers.contains()を使えば全ての要素を指定してアサートできます。
public class SampleBeanTest { @Test public void test() { List<String> actual = Arrays.asList("test1", "test2", "test3"); assertThat(actual, contains("test1", "test2", "test3")); // OK } }
ちなみにisでもアサートできました。。
public class SampleBeanTest { @Test public void test() { List<String> actual = Arrays.asList("test1", "test2", "test3"); List<String> expected = Arrays.asList("test1", "test2", "test3"); assertThat(actual, is(expected)); // OK } }
参考
JUnit4 で List の assertThat を簡潔に書きたい
List(JavaBean)のアサート
今のところ、よい方法が思いつかないです。
Listを要素ごとにアサートするのは面倒ですし、Listをfor文でアサートするのも良くないです。
ifやforなどのロジックはテストコードの可読性を下げますし、for文はどこでエラーになったのかがわかりづらいです。
ベターな方法は以下ですかね?
- リストサイズをアサート
- 要素ごとにsamePropertyValuesAsでアサート
それかカスタムマッチャーを作るかです。。
List
JUnit4/カスタムmatcherを作る [Ore Base]