Wie stellen Sie sicher, dass eine Ausnahme nicht geworfen
In meine unit-Tests mit Mockito ich wollen, stellen Sie sicher, dass NullPointerException
wurde nicht geworfen.
public void testNPENotThrown{
Calling calling= Mock(Calling.class);
testClass.setInner(calling);
testClass.setThrow(true);
testClass.testMethod();
verify(calling, never()).method();
}
Mein test-set-up der testClass
Einstellung der Calling
- Objekt und die Eigenschaft so ein, dass die Methode wirft eine NullPointerException
.
Ich überprüfen, dass die Berufung.Methode() wird nie aufgerufen.
public void testMethod(){
if(throw) {
throw new NullPointerException();
}
calling.method();
}
Ich will einen fehlerhaften test, weil es wirft einen NullPointerException
, und dann will ich code schreiben, um dieses Problem zu beheben.
Was ich bemerkt habe, ist, dass der test immer geht als exception wird nie geworfen, bis die test-Methode.
InformationsquelleAutor well_i | 2013-07-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
tl;dr
pre-JDK8 : ich empfehle den guten alten
try
-catch
block.post-JDK8 : Verwenden Sie AssertJ oder benutzerdefinierte lambdas zu behaupten außergewöhnliche Verhalten.
die lange Geschichte
Ist es möglich, zu schreiben, selbst eine do it yourself
try
-catch
block oder verwenden Sie den JUnit-tools (@Test(expected = ...)
oder die@Rule ExpectedException
JUnit Regel-Funktion).Aber diese Wege sind nicht so elegant und nicht gut mischen Lesbarkeit weisen mit anderen tools.
Den
try
-catch
block, den Sie haben, zu schreiben, der block rund um das getestete Verhalten, und schreiben Sie die Behauptung in den catch-block, kann in Ordnung sein, aber viele finden, die dieser Stil unterbricht den Lesefluss ein test. Auch Sie müssen schreiben Sie eineAssert.fail
am Ende dertry
blockieren, sonst kann der test verpassen die eine Seite der Behauptungen ; PMD, findbugs oder Sonar werden vor Ort solche Themen.Den
@Test(expected = ...)
feature ist interessant, da können Sie weniger code schreiben und dann schreiben, dieser test ist angeblich weniger anfällig für Fehler codieren. Aber ths Ansatz ist, fehlen einige Bereiche.Als auch die Erwartung ist um in der Methode, je nachdem, wie die getesteten code geschrieben wird, dann die falschen Teil der test-code kann werfen die Ausnahme, was zu falsch-positiven test, und ich m nicht sicher, dass PMD, findbugs oder Sonar geben Hinweise auf einen solchen code.
Den
ExpectedException
Regel ist auch ein Versuch, zu beheben die früheren Vorbehalte, aber es fühlt sich ein wenig umständlich zu bedienen, da Sie mit einer Erwartungshaltung der Art, EasyMock Benutzer kennt sich sehr gut mit diesem Stil. Es mag bequem sein für einige, aber wenn Sie Folgen Behaviour Driven Development (BDD) oder Arrange-Act-Assert (AAA) Grundsätze derExpectedException
Regel passt nicht in diesen Schreibstil. Abgesehen von, kann es leiden unter dem gleichen Problem wie die als@Test
Weise, je nachdem, wo Sie Platz der Erwartung.Sogar die erwartete Ausnahme ist angebracht, bevor der test-Anweisung, es bricht Ihrer Lesefluss, wenn die tests Folgen, BDD oder AAA.
Sehen das auch Kommentar Problem auf JUnit des Autors
ExpectedException
.Also diese oben genannten Möglichkeiten haben alle Ihre Last von Einsprüchen, und eindeutig nicht immun gegen coder Fehler.
Es ist ein Projekt, wurde mir bewusst nach dem erstellen dieser Antwort, dass sieht vielversprechend aus, es ist catch-exception.
Als die Beschreibung des Projekts, sagt, lassen Sie es ein coder schreiben in eine fließende Linie der code die exception zu fangen und bieten diese Ausnahme für die spätere Geltendmachung. Und Sie können jede assertion-Bibliothek, wie Hamcrest oder AssertJ.
Einen schnellen Beispiel, genommen von der Homepage :
Wie Sie sehen können, der code ist wirklich ganz einfach, man fängt die Ausnahme auf eine bestimmte Zeile, die
then
API ist ein alias verwenden, die AssertJ APIs (ähnlich wie mitassertThat(ex).hasNoCause()...
). Irgendwann das Projekt stützte sich auf die FEST Behaupten, die Vorfahren der AssertJ. EDIT: Es scheint, das Projekt Brau-Java 8 Lambda-Ausdrücke unterstützen.Derzeit diese Bibliothek hat zwei Mängel :
Zur Zeit dieses Schreibens ist es bemerkenswert, zu sagen, diese Bibliothek basiert auf Mockito 1.x wie schafft es ein mock von dem getesteten Objekt hinter der Szene. Wie Mockito ist noch nicht aktualisiert dieser library kann die Arbeit mit final Klassen-oder final-Methoden. Und selbst wenn es war, basierend auf mockito 2 in der aktuellen version, dies würde es erforderlich machen, deklarieren Sie eine Globale mock maker (
inline-mock-maker
), etwas, das vielleicht nicht das, was Sie wollen, als dieser mockmaker hat verschiedene Nachteile, dass die regelmäßige mockmaker.Benötigt es noch einen weiteren test Abhängigkeit.
Diese Probleme nicht anzuwenden, sobald die Bibliothek unterstützt Lambda-Ausdrücke, aber die Funktionalität wird dupliziert AssertJ toolset.
Berücksichtigung aller in Betracht, wenn Sie nicht wollen, verwenden Sie die catch-Ausnahme-tool, ich empfehle dir den guten alten Weg der
try
-catch
block, zumindest bis zu dem JDK7. Und für JDK 8 Benutzern, die Sie bevorzugen könnte, um zu verwenden AssertJ, wie es bietet mehr als nur die Geltendmachung von Ausnahmen.Mit dem JDK8, lambdas geben Sie die test-Szene, und Sie haben erwies sich als eine interessante Art und Weise zu behaupten außergewöhnliches Verhalten. AssertJ wurde aktualisiert und bietet einen schönen fluent-API zu behaupten außergewöhnliches Verhalten.
Und eine Probe mit AssertJ :
Einen fast kompletten rewrite des JUnit-5, Behauptungen wurden verbessert ein bisschen, Sie beweisen können, interessant, wie eine out-of-the-box-Art geltend zu machen, richtig Ausnahme. Aber wirklich die Behauptung API ist noch ein wenig dürftig, es gibt nichts außerhalb
assertThrows
.Als Sie bemerkte
assertEquals
ist immer noch die Rückkehrvoid
, und als solche nicht erlaubt, die Verkettung von Assertionen, wie AssertJ.Auch, wenn Sie sich erinnern Namen Zusammenstoß mit
Matcher
oderAssert
, werden vorbereitet, um die gleiche Zusammenstoß mitAssertions
.Ich möchte zu dem Schluss, dass heute (2017-03-03) AssertJ's Benutzerfreundlichkeit, erkennbar API, die schnelle Tempo der Entwicklung und als de facto test-Abhängigkeit ist die beste Lösung mit JDK8 unabhängig von dem test-framework (JUnit oder nicht), vor JDKs sollte stattdessen auf
try
-catch
Blöcke, auch wenn Sie das Gefühl umständlich.InformationsquelleAutor Brice
Wenn ich dont verstehen Sie falsch, Sie müssen so etwas wie dieses:
aber durch die Benennung der test "NPENotThrown" ich würde erwarten, dass ein test wie dieser:
InformationsquelleAutor Stefan Beike
Ein weiterer Ansatz ist die Verwendung von try/catch statt. Es ist ein bisschen unordentlich, aber von was ich verstehe, dieser test wird von kurzer Dauer sein sowieso, da es für TDD:
EDIT: ich war in Eile als ich dies schrieb. Was meine ich mit 'dieser test wird von kurzer Dauer sein sowieso, da es für TDD ist, dass Sie sagen, Sie gehen, code zu schreiben, dies zu beheben, testen Sie sofort, so wird es nie werfen einer NullPointerException in die Zukunft. Dann könnte man genauso gut löschen Sie den test. Daher ist es wahrscheinlich nicht Wert, viel Zeit damit verbringen, zu schreiben einen schönen test (daher mein Vorschlag :-))
Allgemein:
Beginnen mit einem test, um zu behaupten, dass (zum Beispiel) den Rückgabewert einer Methode ist nicht null, ist ein etabliertes TDD-Prinzip, und die überprüfung auf eine NullPointerException (NPE) ist ein möglicher Weg zu gehen über diese. Jedoch Ihre Produktions-code ist vermutlich nicht zu einem Fluss, wo eine NPE geworfen wird. Sie gehen auf null prüfen und dann tun Sie etwas vernünftiges, kann ich mir vorstellen. Würde, dass diese bestimmten test überflüssig an dieser Stelle, wie es sein wird die Prüfung einer NPE wird nicht ausgelöst, wenn in der Tat es nie passieren kann. Dann könnten Sie ersetzen Sie es mit einem test überprüft, was passiert, wenn eine null Auftritt: gibt ein NullObject zum Beispiel, oder wirft eine andere Art von Ausnahme, was auch immer angemessen ist.
Es ist natürlich keine Voraussetzung, dass Sie löschen Sie die redundante Prüfung, aber wenn Sie nicht, es wird dort sitzen, so dass jedes bauen etwas langsamer ist, und was jeder Entwickler, der liest den test zu Fragen; "Hmm, eine NPE? Sicherlich hat dieser code kann nicht werfen eine NPE?". Ich habe gesehen, dass viele von TDD-code, in dem der test-Klassen haben eine Menge von redundanten tests wie dieser. Wenn es die Zeit erlaubt, es zahlt sich aus zu überprüfen, Ihre tests, die jeder so oft.
InformationsquelleAutor Mark Chorley
In der Regel jedem Testfall ausgeführt wird mit einer neuen Instanz, so die Einstellung einer Instanz-variable wird nicht helfen. So machen '
throw
' variable statisch ist, wenn nicht.InformationsquelleAutor Juned Ahsan