2013-05-16 11 views
21

いくつかのメソッドをテストするためにいくつかのテストケースを書きました。しかし、いくつかのメソッドは例外をスローします。私はそれを正しくしていますか?私は-45を渡すとjunitで例外を処理する方法

private void testNumber(String word, int number) { 
    try { 
     assertEquals(word, service.convert(number)); 
    } catch (OutOfRangeNumberException e) { 
     Assert.fail("Test failed : " + e.getMessage()); 
    } 
} 

@Test 
public final void testZero() { 
    testNumber("zero", 0); 
} 

、それはOutOfRangeExceptionで失敗しますが、私はあなたがテストに失敗する例外をキャッチする必要はありません@Test(Expected...)

答えて

6

のような特定の例外をテストすることはできませんよ。とにかく(throwsと宣言して)放置すると、とにかく失敗します。

もう1つのケースは、実際に例外が予想される場合です。次にtryブロックの最後に失敗します。例えば

@Test 
public void testInvalidNumber() { 
    try { 
     String dummy = service.convert(-1)); 
     Assert.fail("Fail! Method was expected to throw an exception because negative numbers are not supported.") 
    } catch (OutOfRangeException e) { 
     // expected 
    } 
} 

あなたはあなたのコードを正しく入力を検証し、適切な例外を除いて、無効な入力を処理しているかどうかを確認するためのテストのこの種を使用することができます。

+1

ExpectedExceptionは期待例外をテストするための好ましい方法です。 –

+0

私は同意すると私はすでにエリックの答えをupvotedしました。 – javadeveloper

+0

例外の構造をチェックする必要がある場合は、ExpectedExceptionが必要です。たとえば、CmisExceptionsには特定の障害理由が設定されていると想定されます。私はそれを確認するためのテストを書かなければなりませんでした、そして私はその目的のためにHamcrest matchersを使いました。例外が予想される場合は、@Testの引数を使用します。 –

15

のように、try-catchブロックを削除し、あなたの試験方法にthrows Exceptionを追加:JUnitのは失敗のテストは、あなたにそれらをキャッチするだけでそれらを適切に報告することができることから、JUnitのを停止され、例外がスローされます期待し

@Test 
public final void testZero() throws Exception { 
    assertEquals("zero", service.convert(0)); 
} 

。このようにして、@Testアノテーションの期待されるプロパティも機能します。

45

予期しない例外はテストの失敗であるため、あなたはそれをキャッチする必要も、もう1つもキャッチしたくありません。 strは簡単なテストの失敗となり、それに小数点を持っているのでserviceまで

@Test 
public void canConvertStringsToDecimals() { 
    String str = "1.234"; 
    Assert.assertEquals(1.234, service.convert(str), 1.0e-4); 
} 

IllegalArgumentExceptionをスローしません。

予期しない例外は、expectedオプションの引数@Testで処理する必要があります。

@Test(expected=NullPointerException.class) 
public void cannotConvertNulls() { 
    service.convert(null); 
} 

プログラマは怠け者だったとExceptionを投げ、または彼はserviceリターン0.0を持っていた場合、テストは失敗します。 NPEのみが成功します。予想される例外のサブクラスも機能することに注意してください。 NPEではまれですが、IOExceptionSQLExceptionと共通です。

まれに特定の例外メッセージをテストする場合は、新しいExpectedException JUnit @Ruleを使用します。今

@Rule 
public ExpectedException thrown= ExpectedException.none(); 
@Test 
public void messageIncludesErrantTemperature() { 
    thrown.expect(IllegalArgumentException.class); 
    thrown.expectMessage("-400"); // Tests that the message contains -400. 
    temperatureGauge.setTemperature(-400); 
} 

設定温度はIAEをスローし、メッセージは、ユーザが設定しようとしていた温度が含まれていない限り、テストは失敗します。このルールは、より洗練された方法で使用できます。


あなたの例では、最高で扱うことができます。

private void testNumber(String word, int number) 
     throws OutOfRangeNumberException { 
    assertEquals(word, service.convert(number)); 
} 

@Test 
public final void testZero() 
     throws OutOfRangeNumberException { 
    testNumber("zero", 0); 
} 

あなたはtestNumberをインライン化することができます。今、それはあまり役に立たない。これをパラメータ化されたテストクラスにすることができます。

2

テストで予想される例外に対処するためには、いくつかの方法があります。私は、JUnitアノテーションとtry/catchイディオムは既に上記のとおりだと思います。私はラムダ式のJava 8オプションに注意を向けたいと思います。例えば

与えられた:

class DummyService { 
public void someMethod() { 
    throw new RuntimeException("Runtime exception occurred"); 
} 

public void someOtherMethod(boolean b) { 
    throw new RuntimeException("Runtime exception occurred", 
      new IllegalStateException("Illegal state")); 
} 

}

をあなたがこれを行うことができます:

@Test 
public void verifiesCauseType() { 
    // lambda expression 
    assertThrown(() -> new DummyService().someOtherMethod(true)) 
      // assertions 
      .isInstanceOf(RuntimeException.class) 
      .hasMessage("Runtime exception occurred") 
      .hasCauseInstanceOf(IllegalStateException.class); 
} 

は例とオプションのほとんどをカバーして、このブログを見てみましょう。

http://blog.codeleak.pl/2013/07/3-ways-of-handling-exceptions-in-junit.html

そして、この1は、より完全にするJava 8のラムダオプションについて説明します。

http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html

関連する問題