webentwicklung-frage-antwort-db.com.de

Testen auf mehrere Ausnahmen mit JUnit 4-Anmerkungen

Kann in einem einzigen JUnit-Komponententest auf mehrere Ausnahmen getestet werden? Ich weiß für eine einzige Ausnahme, die man zum Beispiel verwenden kann

    @Test(expected=IllegalStateException.class)

Wenn ich nun auf eine andere Ausnahme testen möchte (zB NullPointerException), kann dies in derselben Annotation, in einer anderen Annotation erfolgen, oder muss ich einen anderen Komponententest vollständig schreiben?

24
phantom-99w

Sie wollen wirklich, dass der Test One - Ding tut, und dies zu testen. Wenn Sie nicht sicher sind, welche Ausnahme ausgelöst wird, klingt das für mich nicht nach einem guten Test.

z.B. (in Pseudo-Code)

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
}

wenn Sie also testen möchten, dass Ihre Methode zwei unterschiedliche Ausnahmen (für 2 Eingangssätze) auslöst, benötigen Sie 2 Tests.

22
Brian Agnew

Dies ist mit der Annotation nicht möglich.

Mit JUnit 4.7 können Sie die neue Regel ExpectedException verwenden

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

Mehr sehen


Wenn für Sie kein Update auf JUnit 4.7 möglich ist, müssen Sie einen bloßen Unit-Test des Formulars schreiben

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

}

12
akuhn

Verwenden Sie 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

Obwohl dies mit JUnit 4 nicht möglich ist, ist es ist möglich, wenn Sie zu TestNG wechseln, wodurch Sie schreiben können 

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

Halten Sie die Tests so einfach und kurz wie möglich. Die Absicht eines JUnit-Tests ist es, nur eine einfache Funktionalität oder einen einzelnen Ausfallweg zu testen.

Um sicher zu gehen, sollten Sie für jeden möglichen Ausführungsweg mindestens einen Test erstellen.

Normalerweise ist dies nicht immer möglich, denn wenn Sie eine Methode haben, die eine Zeichenfolge analysiert, gibt es so viele mögliche Zeichenkombinationen, dass Sie nicht alles abdecken können.

Halte es kurz und einfach.

Sie können problemlos 30-40 Testmethoden für eine einzelne Methode haben ... ist das wirklich wichtig?

Grüße

0
Atmocreations

Wie würden Sie erwarten, dass "erwartet" wird, um zu funktionieren? Eine Methode kann nur eine Ausnahme auslösen.

Sie müssten für jede Methode, zu der die Methode fehlschlagen kann, einen anderen Komponententest schreiben. Wenn also die Methode zwei Ausnahmen zulässt, müssen zwei Tests eingerichtet werden, um die Methode zum Auslösen jeder Ausnahme zu erzwingen.

@Test(expected=Exception.class)

Dadurch werden alle möglichen Ausnahmen ausgelöst.

0
Raj