web-dev-qa-db-ja.com

JUnit 4アノテーションを使用した複数の例外のテスト

単一のJUnit単体テストで複数の例外をテストすることは可能ですか?たとえば、1つの例外で使用できることを知っています。

    @Test(expected=IllegalStateException.class)

ここで、別の例外(たとえば、NullPointerException)をテストしたい場合、これは同じアノテーション、別のアノテーションで行うことができますか、それとも別の単体テストを完全に記述する必要がありますか?

26
phantom-99w

あなたは本当にテストがone事を行い、それをテストすることを望んでいます。どの例外がスローされるかわからない場合、それは私にとって良いテストのようには思えません。

例えば(疑似コード)

try {
   badOperation();
   /// looks like we succeeded. Not good! Fail the test
   fail();
}
catch (ExpectedException e) {
   // that's fine
}
catch (UnexpectedException e) {
   // that's NOT fine. Fail the test
}

したがって、メソッドが2つの異なる例外(2セットの入力に対して)をスローすることをテストする場合は、2つのテストが必要になります。

23
Brian Agnew

これは注釈では不可能です。

JUnit 4.7では、新しいExpectedExceptionルールを使用できます

public static class HasExpectedException {
    @Interceptor
    public ExpectedException thrown= new ExpectedException();

    @Test
    public void throwsNothing() {
    }

    @Test
    public void throwsNullPointerException() {
         thrown.expect(NullPointerException.class);
         throw new NullPointerException();
    }

    @Test
    public void throwsNullPointerExceptionWithMessage() {
        thrown.expect(NullPointerException.class);
        thrown.expectMessage("happened?");
        throw new NullPointerException("What happened?");
    }
}

もっと見る


JUnit 4.7に更新できない場合は、フォームの単体テストを作成する必要があります

public test() {
    try {
        methodCall(); // should throw Exception
        fail();
    }
    catch (Exception ex) {
        assert((ex instanceof A) || (ex instanceof B) || ...etc...);
        ...
    }

}

12
akuhn

JUnit 4ではこれは不可能ですが、TestNGに切り替えるとisが可能になり、次のように記述できます。

@Test(expectedExceptions = {IllegalArgumentException.class, NullPointerException.class})
4

catch-exception を使用します。

// test 
public void testDo() {

   // obj.do(1) must throw either A or B
   catchException(obj).do(1);
   assert caughtException() instanceof A
       || caughtException() instanceof B;

   // obj.do(2) must throw A but not SubclassOfA
   catchException(obj).do(2);
   assert caughtException() instanceof A
       && !(caughtException() instanceof SubclassOfA);

}
3
rwitzel
@Test(expected=Exception.class)

これにより、すべての可能な例外がスローされます。

1
Raj

テストはできるだけ簡潔かつ簡潔にしてください。 JUnit-Testの目的は、1つの単純な機能または1つの単一の障害方法のみをテストすることです。

実際、安全のために、可能なすべての実行方法に対して少なくとも1つのテストを作成する必要があります。

通常、これは常に可能であるとは限りません。文字列を分析するメソッドがある場合、文字列の組み合わせが多すぎてすべてをカバーできないためです。

短く簡潔にしてください。

1つのメソッドに対して30〜40のテストメソッドを簡単に設定できます。

よろしく

0
Atmocreations

「期待される」がどのように機能すると期待しますか?メソッドがスローできる例外は1つだけです。

メソッドが失敗する可能性のある方法ごとに、異なる単体テストを作成する必要があります。したがって、メソッドが2つの例外を合法的にスローする場合は、2つのテストをセットアップして、各例外をスローするメソッドを強制する必要があります。