JUnit4 による例外発生時のメッセージのテスト
JUnit 4.7 からの機能で、例外が throw
されたときのメッセージ(getMessage
で取得できる文字列)をチェックすることが出来るようになったらしい。具体的には、同じ例外クラスを throw
するが、ケースによってメッセージが変わるような場合に、@Test(expected = ...)
では確認しきれないので、この方法を使うようである。
実際例
前回の例を修正して、今回の実際例として用いる。
ChangeNum
クラスの修正
package jp.mydns.akanekodou; /** * <p>整数を表す文字列を整数に変換する</p> * * @version 1.1 * @author Red cat */ public class ChangeNum { /** * <p>数値文字列を整数に変換する</p> * * @param str 整数を表す文字列 * @return 変換された整数値 * @throws NumberFormatException 引数の文字列が整数値を表していないとき * @see Integer#parseInt(String) */ public int changeNum(String str) throws NumberFormatException { try { return Integer.parseInt(str); } catch(NumberFormatException e) { // NumberFormatException を catch したら // メッセージつきの NumberFormatException を throw する throw new NumberFormatException("入力された値が整数値を表していません。"); } } }
NumberFormatException
を catch
した際に、エラーメッセージを独自に設定した NumberFormatException
を新たに throw
する仕様に変更している。
例外検証ルールの作成
@Rule
アノテーションと ExpectedException
クラスを利用して検証ルールを作成する。
package jp.mydns.akanekodou.test.junit4; import jp.mydns.akanekodou.ChangeNum; import org.junit.*; import org.junit.rules.ExpectedException; import static org.junit.Assert.*; import static org.hamcrest.core.Is.is; /** * <p>JUnit4 による ChangeNum テスト用クラス</p> * * @author Red cat */ public class ChangeNumTest { private static ChangeNum target; @Rule public ExpectedException thrown = ExpectedException.none(); /** * <p> * テスト前処理<br /> * 全体を通して 1 回だけ実行 * </p> */ @BeforeClass public static void getTestClass() { target = new ChangeNum(); } /** * <p>正常系テスト</p> */ @Test public void success() { String str = "100"; int expected = 100; int actual = target.changeNum(str); assertThat("数値に変換されていません。", actual, is(expected)); } /** * <p>異常系テスト</p> */ @Test public void exception() { String str = "99.9"; // 整数を表していない ! // 例外検証ルールの設定 thrown.expect(NumberFormatException.class); thrown.expectMessage("入力された値が整数値を表していません。"); target.changeNum(str); // ここで NumberFormatException が発生するはず } }
これで期待される例外のみならず、その際に期待されるエラーメッセージも一致したときに限って異常系のテストが成功する。
(参考)JUnit3 による例外発生時のメッセージテスト
JUnit3 の場合はことがもう少し簡単(?)で、一行追加するだけである。
package jp.mydns.akanekodou.test.junit3; import jp.mydns.akanekodou.ChangeNum; import junit.framework.*; /** * <p>JUnit3 による ChangeNum テスト用クラス</p> * * @author Red cat */ public class ChangeNumTest extends TestCase { private ChangeNum target; /** * <p>コンストラクタ</p> * * @param name {@inheritDoc} * @see TestCase#TestCase(String) */ public ChangeNumTest(String name) { super(name); } /** * <p> * テスト前処理<br /> * 各テストメソッドの前に毎回実行 * </p> * * @see TestCase#setUp() */ @Override public void setUp() { target = new ChangeNum(); } /** * <p>正常系テスト</p> */ public void testSuccess() { String str = "100"; int expected = 100; int actual = target.changeNum(str); assertEquals("数値に変換されていません。", expected, actual); } /** * <p>異常系テスト</p> */ public void testException() { String str = "99.9"; // 整数を表していない ! try { target.changeNum(str); // ここで NumberFormatException が発生するはず fail("例外が発生していません。"); } catch(NumberFormatException e) { assertEquals("入力された値が整数値を表していません。", e.getMessage()); } } }