29

いくつかのメソッドをテストするためにいくつかのテストケースを書きました。ただし、一部のメソッドは例外をスローします。私はそれを正しくやっていますか?

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);
}

合格-45すると失敗しますOutOfRangeExceptionが、次のような特定の例外をテストできません@Test(Expected...)

4

4 に答える 4

52

予期しない例外はテストの失敗であるため、キャッチする必要も、キャッチする必要もありません。

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

小数点が含まれているため、 untilserviceはスローされません。これは、単純なテストの失敗になります。IllegalArgumentExceptionstr

予想される例外は、 のオプションのexpected引数によって処理する必要があり@Testます。

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

プログラマーが怠け者で を投げたException場合、または をservice返し0.0た場合、テストは失敗します。だけNPEが成功します。予想される例外のサブクラスも機能することに注意してください。これは s ではまれですが、 s とsNPEでは一般的です。IOExceptionSQLException

特定の例外メッセージをテストしたいというまれなケースでは、新しいExpectedExceptionJUnitを使用します@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);
}

setTemperature が をスローし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。今ではあまり役に立ちません。これをパラメータ化されたテスト クラスに変換できます。

于 2013-05-16T20:46:14.383 に答える
24

try-catch ブロックを削除し、次のthrows Exceptionようにテスト メソッドに追加します。

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

JUnit は、失敗したテストが例外をスローすることを期待しています。それらをキャッチすると、JUnit がそれらを適切に報告できなくなります。また、この方法で @Test アノテーションの期待されるプロパティが機能します。

于 2013-05-16T20:11:35.950 に答える
7

テストに失敗するために例外をキャッチする必要はありません。(宣言して)手放すだけで、throwsとにかく失敗します。

もう 1 つのケースは、実際に例外が予想される場合で、try ブロックの最後に fail を置きます。

例えば:

@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
  }
}

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

于 2013-05-16T20:06:31.907 に答える
5

テストで予想される例外に対処するために、いくつかの方法があります。JUnit アノテーションと try/catch イディオムは既に上で言及されていると思います。Lambda 式の 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

そして、これはJava 8 Lambdaオプションをより完全に説明しています:

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

于 2015-07-20T15:24:54.937 に答える