fail()
In der JUnit4-Bibliothek gibt es eine Methode. Ich mag es, aber es mangelt an pass()
Methoden, die in der Bibliothek nicht vorhanden sind. Wieso ist es so?
Ich habe herausgefunden, dass ich assertTrue(true)
stattdessen verwenden kann, aber immer noch unlogisch aussieht.
@Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}
// assertTrue(true);
}
pass
Methode.Antworten:
Solange der Test keine Ausnahme auslöst, besteht er, es sei denn, Ihre
@Test
Anmerkung gibt eine erwartete Ausnahme an. Ich nehme an, dass apass()
eine spezielle Ausnahme auslösen könnte, die JUnit immer als bestanden interpretiert, um den Test kurzzuschließen, aber dies würde gegen das übliche Design von Tests verstoßen (dh Erfolg annehmen und nur scheitern, wenn eine Behauptung fehlschlägt) und wenn Leute es bekommen Die Idee, dass die Verwendung vorzuziehen istpass()
, würde eine große Anzahl bestehender Tests erheblich verlangsamen (aufgrund des Overheads bei der Erstellung von Ausnahmen). Fehlgeschlagene Tests sollten nicht die Norm sein, daher ist es keine große Sache, wenn sie diesen Overhead haben.Beachten Sie, dass Ihr Beispiel folgendermaßen umgeschrieben werden könnte:
@Test(expected=IncorrectArgumentForSetter.class) public void testSetterForeignWord("") throws Exception { card.setForeignWord(""); }
Außerdem sollten Sie die Verwendung von Standard-Java-Ausnahmen bevorzugen. Du
IncorrectArgumentForSetter
solltest wahrscheinlich ein seinIllegalArgumentException
.quelle
pass()
Methode nicht einfach nichts tun kann, damit ein Test nach dem Aufruf nicht fehlschlägt. Also habe ich diesen Satz entfernt.Rufen Sie die
return
Anweisung immer dann an, wenn Ihr Test beendet und bestanden ist.quelle
Ich denke, diese Frage muss aktualisiert werden, da die meisten Antworten hier ziemlich veraltet sind.
Zunächst zur Frage des OP:
Ich denke, es ist ziemlich gut akzeptiert, dass die Einführung des Konzepts der "erwarteten Ausnahme" in JUnit ein schlechter Schachzug war, da diese Ausnahme überall ausgelöst werden könnte und den Test bestehen wird. Es funktioniert, wenn Sie sehr domänenspezifische Ausnahmen auslösen (und geltend machen), aber ich werfe nur solche Ausnahmen aus, wenn ich an Code arbeite, der absolut makellos sein muss. Die meisten APIS lösen einfach die eingebauten Ausnahmen wie
IllegalArgumentException
oder ausIllegalStateException
. Wenn zwei Aufrufe, die Sie tätigen, diese Ausnahmen möglicherweise auslösen könnten,@ExpectedException
wird Ihr Test durch die Anmerkung grün markiert, selbst wenn es sich um die falsche Zeile handelt, die die Ausnahme auslöst !Für diese Situation habe ich eine Klasse geschrieben, die sicher viele andere hier geschrieben haben. Das ist eine
assertThrows
Methode:public class Exceptions { private Exceptions(){} public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){ try{ actionThatShouldThrow.run(); fail("expected action to throw " + expectedException.getSimpleName() + " but it did not."); } catch(Exception e){ if ( ! expectedException.isInstance(e)) { throw e; } } } }
Diese Methode wird einfach zurückgegeben, wenn die Ausnahme ausgelöst wird, sodass Sie in Ihrem Test weitere Zusicherungen / Überprüfungen vornehmen können.
Mit der Java 8-Syntax sieht Ihr Test wirklich gut aus. Im Folgenden finden Sie einen der einfacheren Tests für unser Modell, bei dem die Methode verwendet wird:
@Test public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() { //setup AxisRange range = new AxisRange(0,100); //act Runnable act = () -> range.setLowerBound(200); //assert assertThrows(IllegalArgumentException.class, act); }
Diese Tests sind ein wenig wackelig, weil der Schritt "Akt" eigentlich keine Aktion ausführt, aber ich denke, die Bedeutung ist immer noch ziemlich klar.
Es gibt auch eine winzige kleine Bibliothek auf maven namens catch-exception , die die Syntax im Mockito-Stil verwendet, um zu überprüfen, ob Ausnahmen ausgelöst werden. Es sieht hübsch aus, aber ich bin kein Fan von dynamischen Proxys. Trotzdem ist die Syntax so raffiniert, dass sie verlockend bleibt:
// given: an empty list List myList = new ArrayList(); // when: we try to get the first element of the list // then: catch the exception if any is thrown catchException(myList).get(1); // then: we expect an IndexOutOfBoundsException assert caughtException() instanceof IndexOutOfBoundsException;
Für die Situation, in die ich geraten bin, um zu diesem Thread zu gelangen, gibt es eine Möglichkeit , Tests zu ignorieren , wenn eine Bedingung erfüllt ist.
Im Moment arbeite ich daran, einige DLLs über eine Java-Bibliothek zum Laden nativer Bibliotheken namens JNA aufzurufen, aber unser Build-Server befindet sich in Ubuntu. Ich versuche gerne, diese Art von Entwicklung mit JUnit-Tests voranzutreiben - auch wenn sie zu diesem Zeitpunkt weit von "Einheiten" entfernt sind -. Ich möchte den Test ausführen, wenn ich mich auf einem lokalen Computer befinde, den Test jedoch ignorieren, wenn wir Ubuntu verwenden. JUnit 4 hat hierfür eine Bestimmung namens
Assume
:@Test public void when_asking_JNA_to_load_a_dll() throws URISyntaxException { //this line will cause the test to be branded as "ignored" when "isCircleCI" //(the machine running ubuntu is running this test) is true. Assume.assumeFalse(BootstrappingUtilities.isCircleCI()); //an ignored test will typically result in some qualifier being put on the results, //but will also not typically prevent a green-ton most platforms. //setup URL url = DLLTestFixture.class.getResource("USERDLL.dll"); String path = url.toURI().getPath(); path = path.substring(0, path.lastIndexOf("/")); //act NativeLibrary.addSearchPath("USERDLL", path); Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class); //assert assertThat(dll).isNotNull(); }
quelle
Ich suchte auch nach einer
pass
Methode für JUnit, um einige Tests kurzschließen zu können, die in einigen Szenarien nicht anwendbar waren (es gibt Integrationstests anstelle von reinen Komponententests). Schade, dass es nicht da ist.Glücklicherweise gibt es eine Möglichkeit, einen Test bedingt ignorieren zu lassen, was in meinem Fall sogar noch besser passt, wenn folgende
assumeTrue
Methode verwendet wird:Hier wird der Test also nur ausgeführt, wenn isTestApplicable wahr ist, andernfalls wird der Test ignoriert.
quelle
Die Pass-Methode ist nicht erforderlich, da der Unit-Testfall bestanden wird, wenn keine AssertionFailedException aus dem Testcode ausgelöst wird.
Die fail () -Methode löst tatsächlich eine AssertionFailedException aus, um den TestCase nicht zu bestehen, wenn die Steuerung an diesem Punkt angelangt ist.
quelle
Ich denke, dass diese Frage das Ergebnis eines kleinen Missverständnisses des Testausführungsprozesses ist. In JUnit (und anderen Testtools) werden die Ergebnisse pro Methode und nicht pro Assert-Aufruf gezählt. Es gibt keinen Zähler, der festhält, wie viele bestanden / nicht bestanden
assertX
ausgeführt wurden.JUnit führt jede Testmethode separat aus. Wenn die Methode erfolgreich zurückgegeben wird, wird der Test als "bestanden" registriert. Wenn eine Ausnahme auftritt, wird der Test als "fehlgeschlagen" registriert. Im letzteren Fall sind zwei Unterfälle möglich: 1) eine JUnit-Assertionsausnahme, 2) jede andere Art von Ausnahmen. Der Status wird im ersten Fall "fehlgeschlagen" und im zweiten Fall "Fehler" sein.
In der
Assert
Klasse stehen viele Kurzmethoden zur Verfügung, um Assertionsausnahmen auszulösen. Mit anderen Worten,Assert
ist eine Abstraktionsschicht über JUnits Ausnahmen.Dies ist beispielsweise der Quellcode von
assertEquals
auf GitHub :/** * Asserts that two Strings are equal. */ static public void assertEquals(String message, String expected, String actual) { if (expected == null && actual == null) { return; } if (expected != null && expected.equals(actual)) { return; } String cleanMessage = message == null ? "" : message; throw new ComparisonFailure(cleanMessage, expected, actual); }
Wie Sie sehen können, passiert im Falle der Gleichheit nichts, sonst wird eine Ausnahme geworfen.
Damit:
assertEqual("Oh!", "Some string", "Another string!");
ComparisonFailure
löst einfach eine Ausnahme aus, die von JUnit abgefangen wird, undassertEqual("Oh?", "Same string", "Same string");
tut nichts.
In der Summe
pass()
würde so etwas keinen Sinn ergeben, weil es nichts getan hat.quelle