はじめに
JUnit で例外が発生することをテストしたいときは、 @Test
アノテーションで expected
を設定するのがたぶん最も簡単な方法かと思います。しかし、例外メッセージの内容を検証したり、さらには Caused By の例外オブジェクトも検証したい、となると、@Test
アノテーションでは力不足となります。
そんなときに org.junit.rules.ExpectedException
ルールを使うと悩みはだいたい解決しますが、ちょっと使い方がわかりづらかったりします (特に Caused By の例外オブジェクトを検証する場合など)。
なので、Caused By の例外オブジェクトの検証方法を中心に、サンプルコードをメモメモしておきます。
サンプルコードとちょっとした解説
まずはサンプルコードをご覧ください。
ExpectedExceptionDemo.java
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.hamcrest.Matchers.*;
public class ExpectedExceptionDemo {
// 例外発生を期待しない場合のために、ExpectedException.none() を設定しておく
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void demo() {
// 投げられてくる例外のクラスとメッセージは以下のように、
// expect() / expectMessage() で期待される値を指定する
expectedException.expect(RuntimeException.class);
expectedException.expectMessage("runtime exception");
// Caused By の例外オブジェクトの検証には expectCause() を使う
expectedException.expectCause(allOf(
// Caused By の例外クラスを以下で指定する
instanceOf(NullPointerException.class),
// 例外メッセージを以下で指定する
hasProperty("message", is("null-po"))));
// 上記では Matchers.allOf() を使っているけれど、
// expectCause() を2回に分けて呼び出しても問題ない
// 実際に例外を発生させてみよう
try {
throw new NullPointerException("null-po");
} catch (NullPointerException e) {
throw new RuntimeException("runtime exception", e);
}
}
}
ポイントは以下のとおり。
-
ExpectedException#expectCause()
メソッドの呼び出しでは、Matcher
オブジェクトを指定する - 一つ目の
Matcher
オブジェクトの指定において、Matchers.instanceOf()
メソッドを利用して、例外オブジェクトの型を検証する - 二つ目の
Matcher
オブジェクトの指定において、Matchers.hasProperty()
メソッドを利用して、message プロパティ、というかException#getMessage()
の呼び出しを期待した例外メッセージの内容を検証する
使い方さえ理解してしまえば、難しくないですよね…!