Ich teste eine Methode mit einer erwarteten Ausnahme. Ich muss auch überprüfen, ob ein Bereinigungscode (für ein verspottetes Objekt) aufgerufen wurde, nachdem die Ausnahme ausgelöst wurde, aber es sieht so aus, als würde diese Überprüfung ignoriert. Hier ist der Code. Ich benutze den Junit ExpectedExceptionRule um die erwartete Ausnahme zu überprüfen.
@Rule
public ExpectedException expectedEx = ExpectedException.none();
@Test
public void testExpectedException()
{
MockedObject mockObj = mock(MockedObj.class);
MySubject subject = new MySubject(mockedObj);
expectedEx.expect(MyException.class);
expectedEx.expectMessage("My exception message.");
subject.someMethodThrowingException();
verify(mockObj).
someCleanup(eq(...));
}
Es scheint wie die verify wird total ignoriert. Egal welche Methode ich einsetze verifymein Test besteht, was ich nicht will.
Irgendeine Idee, warum das passiert?
Jeff Bowmann
ExpectedException Werke von Verpackung Ihrer gesamten Testmethode in einem Try-Catch-Block über a JUnit @Rule. Wenn Ihr Code eine Ausnahme auslöst, geht er den Stack hinauf zum nächsten try/catch, der sich zufällig in der ExpectedException-Instanz befindet (die überprüft, ob es sich um die erwartete Ausnahme handelt).
Wenn in Java eine nicht abgefangene Ausnahme in einer Methode auftritt, kehrt die Steuerung nie zu Anweisungen später in dieser Methode zurück. Hier gelten die gleichen Regeln: Die Kontrolle kehrt nach der Ausnahme nie zu den Anweisungen in Ihrem Test zurück.
Technisch gesehen könnten Sie die Überprüfungen in einen finally-Block stecken, aber das ist es in der Regel eine schlechte Angewohnheit. BEARBEITEN: Ihr zu testendes System löst möglicherweise eine unerwartete Ausnahme oder überhaupt keine Ausnahme aus, wodurch Sie eine hilfreiche Fehlermeldung und Ablaufverfolgung erhalten würden. Wenn dieser Fehler jedoch dazu führt, dass Ihre Überprüfungen oder Behauptungen in der finally block, dann zeigt Java dies anstelle einer Meldung über die unerwartete Ausnahme oder den unerwarteten Erfolg an. Dies kann das Debuggen erschweren, insbesondere weil Ihr Fehler aus Codezeilen stammt, die der Hauptursache des Fehlers folgen, was fälschlicherweise impliziert, dass der Code darüber erfolgreich war.
Wenn Sie den Status nach der Ausnahme wirklich auf Methodenbasis überprüfen müssen, können Sie jederzeit zu dieser Redewendung zurückkehren:
Aktualisieren: Mit den Lambda-Ausdrücken von Java 8 können Sie einen funktionalen Schnittstellenaufruf in einen Try-Block einschließen kurz genug, um nützlich zu sein. Ich kann mir vorstellen, dass die Unterstützung für diese Syntax ihren Weg in viele Standard-Testbibliotheken finden wird.
Warum sollte die Überprüfung in a finally blockieren die Ausnahme schlucken? finally fängt die Ausnahme nicht ab, also wird sie an den Wrapper weitergegeben. Siehe Kevin Welkers Antwort; das funktioniert ganz gut.
– Stefan Frie
16. November 2018 um 14:45 Uhr
@StefanDeitmer Ich entschuldige mich dafür, dass ich es nicht gut artikuliert habe. Wenn Ihr Test besteht, ja, es wird gut funktionieren. Wenn der Test fehlschlägt, kann dies darauf zurückzuführen sein, dass keine Ausnahme ausgelöst wurde ODER die falsche Ausnahme ausgelöst wurde ODER dass ein Nachbedingungszustand fehlgeschlagen ist, über den die Antwort spricht. Das Problem ist, dass eine fehlgeschlagene Überprüfung darauf hinausläuft, eine Ausnahme in a auszulösen finally block, was Sie daran hindern würde, unerwartete Ausnahmen zu sehen und zu debuggen, die die zu testende Methode auslösen kann. Diese unerwartete Ausnahme ist die geschluckte, die ich meine.
– Jeff Bowmann
16. November 2018 um 15:44 Uhr
Sobald Exception in UT geworfen wird, wird der gesamte Code darunter ignoriert.
@Test(expected = Exception.class)
public void testExpectedException() {
MockedObject mockObj = mock(MockedObj.class);
MySubject subject = new MySubject(mockedObj);
subject.doSomething(); // If this line results in an exception then all the code below this will be ignored.
subject.someMethodThrowingException();
verify(mockObj).
someCleanup(eq(...));
}
Um dem entgegenzuwirken und alle getätigten Anrufe zu überprüfen, können wir verwenden Versuchen mit endlich.
Hallo, könnten Sie auf was eingehen then(caughtException()) ist? davon muss ich ausgehen when und verify sind eigentlich Mockito.when und Mockito.verify aber Sie geben nicht die Klasse von an then.
Ich habe das noch nicht ausprobiert, aber zusätzlich zu Jeff Bowmans ausgezeichneter Antwort haben Sie möglicherweise die Wahl, die ExpectedException-Regel mit einem try… finally-Konstrukt zu verwenden, indem Sie Ihre Verify-Anweisung in den finally-Block einfügen.
12056500cookie-checkMockito verifizieren nach Ausnahme Junit 4.10yes