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 aus IllegalStateException
. 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() {
AxisRange range = new AxisRange(0,100);
Runnable act = () -> range.setLowerBound(200);
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:
List myList = new ArrayList();
catchException(myList).get(1);
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 {
Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
URL url = DLLTestFixture.class.getResource("USERDLL.dll");
String path = url.toURI().getPath();
path = path.substring(0, path.lastIndexOf("/"));
NativeLibrary.addSearchPath("USERDLL", path);
Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);
assertThat(dll).isNotNull();
}