Es gibt ein Projekt, auf das ich aufmerksam geworden bin, nachdem ich diese Antwort erstellt habe, das vielversprechend aussieht. Es ist eine Ausnahme .
Wie in der Beschreibung des Projekts angegeben, konnte ein Codierer eine fließende Codezeile schreiben, die die Ausnahme abfängt, und diese Ausnahme für die letztere Behauptung anbieten. Und Sie können jede Assertionsbibliothek wie Hamcrest oder AssertJ verwenden .
Ein schnelles Beispiel von der Homepage:
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
when(myList).get(1);
// then: we expect an IndexOutOfBoundsException
then(caughtException())
.isInstanceOf(IndexOutOfBoundsException.class)
.hasMessage("Index: 1, Size: 0")
.hasNoCause();
Wie Sie sehen können, ist der Code wirklich einfach. Sie fangen die Ausnahme in einer bestimmten Zeile ab. Die then
API ist ein Alias, der AssertJ-APIs verwendet (ähnlich wie bei der Verwendung assertThat(ex).hasNoCause()...
). Irgendwann stützte sich das Projekt auf FEST-Assert, den Vorfahren von AssertJ . EDIT: Es scheint, dass das Projekt eine Java 8 Lambdas-Unterstützung erstellt.
Derzeit weist diese Bibliothek zwei Mängel auf:
Zum Zeitpunkt dieses Schreibens ist es bemerkenswert zu sagen, dass diese Bibliothek auf Mockito 1.x basiert, da sie ein Modell des getesteten Objekts hinter den Kulissen erstellt. Da Mockito immer noch nicht aktualisiert wird, kann diese Bibliothek nicht mit endgültigen Klassen oder endgültigen Methoden arbeiten . Und selbst wenn es in der aktuellen Version auf Mockito 2 basiert, müsste ein globaler Mock Maker ( inline-mock-maker
) deklariert werden , was möglicherweise nicht Ihren Wünschen entspricht, da dieser Mock Maker andere Nachteile hat als der reguläre Mock Maker.
Es erfordert noch eine weitere Testabhängigkeit.
Diese Probleme treten nicht auf, sobald die Bibliothek Lambdas unterstützt. Die Funktionalität wird jedoch vom AssertJ-Toolset dupliziert.
Unter Berücksichtigung aller Aspekte, wenn Sie das Catch-Exception-Tool nicht verwenden möchten, empfehle ich den alten guten Weg des try
- catch
Blocks, zumindest bis zum JDK7. Und für JDK 8-Benutzer bevorzugen Sie möglicherweise die Verwendung von AssertJ, da es möglicherweise mehr als nur das Festlegen von Ausnahmen bietet.
Mit dem JDK8 betreten Lambdas die Testszene und haben sich als interessante Möglichkeit erwiesen, außergewöhnliches Verhalten zu behaupten. AssertJ wurde aktualisiert, um eine flüssige API bereitzustellen, mit der außergewöhnliches Verhalten bestätigt werden kann.
Und ein Beispieltest mit AssertJ :
@Test
public void test_exception_approach_1() {
...
assertThatExceptionOfType(IOException.class)
.isThrownBy(() -> someBadIOOperation())
.withMessage("boom!");
}
@Test
public void test_exception_approach_2() {
...
assertThatThrownBy(() -> someBadIOOperation())
.isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
@Test
public void test_exception_approach_3() {
...
// when
Throwable thrown = catchThrowable(() -> someBadIOOperation());
// then
assertThat(thrown).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
Mit einer nahezu vollständigen Neufassung von JUnit 5 wurden die Behauptungen ein wenig verbessert . Sie können sich als sofort einsatzbereit erweisen, um eine ordnungsgemäße Ausnahme zu behaupten. Aber wirklich, die Assertion-API ist immer noch ein bisschen schlecht, da draußen ist nichts assertThrows
.
@Test
@DisplayName("throws EmptyStackException when peeked")
void throwsExceptionWhenPeeked() {
Throwable t = assertThrows(EmptyStackException.class, () -> stack.peek());
Assertions.assertEquals("...", t.getMessage());
}
Wie Sie bemerkt haben, assertEquals
kehrt es immer noch zurück void
und erlaubt daher keine Verkettung von Behauptungen wie AssertJ.
Auch wenn Sie sich an Namenskonflikte mit Matcher
oder erinnern Assert
, sollten Sie darauf vorbereitet sein, denselben Konflikt mit zu treffen Assertions
.
org.mockito.Mockito.verify
mit verschiedenen Parametern aufrufen , um sicherzustellen, dass bestimmte Dinge geschehen sind (z. B. dass ein Protokollierungsdienst mit den richtigen Parametern aufgerufen wurde), bevor die Ausnahme ausgelöst wurde.