Help us understand the problem. What is going on with this article?

ExpectedException ルールを使いこなしたい

More than 5 years have passed since last update.

はじめに

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() の呼び出しを期待した例外メッセージの内容を検証する

使い方さえ理解してしまえば、難しくないですよね…!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away