2015-03-11 7 views
45

Wir haben eine Testsuite, die hauptsächlich JUnit-Assertions mit Hamcrest-Matchern verwendet. Einer aus unserem Team begann mit AssertJ zu experimentieren und beeindruckte die Leute mit seiner Syntax, Flexibilität und Deklaration. Es gibt eine Funktion, die JUnit bietet, für die ich in AssertJ keine Entsprechung finden kann: Hinzufügen einer benutzerdefinierten Assert-Fehlermeldung.Können Sie AssertJ assertThat eine benutzerdefinierte Nachricht hinzufügen?

Wir vergleichen oft Objekte, die nicht für die menschliche Lesbarkeit gemacht wurden und zufällige IDs oder UUIDs haben und es ist unmöglich zu sagen, was sie mit den darin enthaltenen Daten sagen sollen. Dies ist eine unvermeidliche Situation für unsere Codebasis, leider als Teil des Zwecks, den es erfüllt, Daten zwischen anderen Diensten abzubilden, ohne notwendigerweise zu verstehen, was es ist.

In JUnit bietet die assertThat Methode eine Version mit einem String reason Parameter vor dem Matcher<T> Parameter. Dies macht es trivial, einen kurzen Debug-String hinzuzufügen, der etwas Licht auf das Problem wirft, wie zum Beispiel, was der Vergleich für einen Menschen bedeuten sollte.

AssertJ, auf der anderen Seite, bietet eine jillion verschiedene genericized static assertThat Methoden, die eine Form von interface Assert oder eine der vielen implementierenden Klassen zurückgeben. Diese Schnittstelle bietet keine standardmäßige Möglichkeit zum Festlegen einer benutzerdefinierten Nachricht für Fehler.

Gibt es eine Möglichkeit, diese Funktionalität von der AssertJ API oder einer seiner Erweiterungen zu erhalten, ohne create a custom assert class for every assert type wir möchten Nachrichten hinzufügen?

Antwort

73

Und auf klassische Weise fand ich, was ich nach dem Posten der Frage gesucht hatte. Hoffentlich wird dies es für die nächste Person leichter machen zu finden, ohne zuerst wissen zu müssen, wie es heißt. Die magische Methode ist die täuschend kurze Bezeichnung , die Teil einer anderen Schnittstelle ist, die AbstractAssert implementiert: Descriptable, nicht die Basis Assert-Schnittstelle.

public S as(String description, Object... args)

Stellt die Beschreibung dieses Objekts stütz String.format(String, Object...) Syntax.
Beispiel:

try { 
    // set a bad age to Mr Frodo which is really 33 years old. 
    frodo.setAge(50); 
    // you can specify a test description with as() method or describedAs(), it supports String format args 
    assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33); 
} catch (AssertionError e) { 
    assertThat(e).hasMessage("[check Frodo's age] expected:<[33]> but was:<[50]>"); 
} 

Wo die Zeichenfolge in Anführungszeichen in dem Block catch hasMessage ist, was in Ihrem Unit-Test-Ausgabeprotokoll angezeigt, wenn die Behauptung fehlschlägt.


Ich fand dies durch die failWithMessage Helfer in den in der Frage verbunden custom assert page zu bemerken. Die JavaDoc für diese Methode weist darauf hin, dass es geschützt ist, so dass es von Anrufern nicht verwendet werden kann, um eine benutzerdefinierte Nachricht festzulegen. Es spielt erwähnt jedoch die as Helfer:

Darüber hinaus ist dieses Verfahren keine Beschreibung ehrt Set mit as(String, Object...) oder überschriebene Fehlermeldung durch den Benutzer definiert mit overridingErrorMessage(String, Object...).

... und die overridingErrorMessage Helfer, die mit dem mitgelieferten neuen String, der den Standard AssertJ expected: ... but was:... Nachricht vollständig ersetzt.

Die AssertJ-Homepage erwähnt keinen der Helfer, bis die Seite mit den Hervorhebungen der Features Beispiele für den as-Helper im Abschnitt Soft Assertions zeigt, aber nicht direkt beschreibt, was er tut.

Verwandte Themen