AssertJ - Conditions
Selbstgebaute Test-Bedingungen -- Conditions
Grundsätzlich lassen sich alle Test-Ausdrücke mit den genannten Konstrukten formulieren. Strenggenommen kann man ja jeden Test als
boolean-Ausdruck formulieren und dann auf True oder False prüfen. Das führt jedoch zu unübersichtlichen Tests und zu endlosen
Code-Duplikationen. Wiederkehrende Prüfungen lassen sich mit Hilfe von wiederverwertbaren Conditions
definieren.
Betrachten wir dazu als einfaches Beispiel (der Einfachheit halber ohne getter und setter) eine Person die einen Namen
hat und einer Abteilung zugeordnet ist:
class Person { String name; String abteilung; Person(String name, String abteilung) { this.name = name; this.abteilung = abteilung; } @Override public String toString() { return name; } }
Um zu testen ob eine Person zur Abteilung "X" gehört, können wir ein Prädikat verwenden und mit Hilfe der
Methode matches()
nutzen, die hier beschrieben ist:
Assertions.assertThat(person).matches(p -> p.abteilung.equals("X")); Assertions.assertThat(person).matches(p -> p.abteilung.equals("X"), "ist in X");
Funktional sind beide Varianten identisch, die Angabe der Beschreibung im zweiten Falle erleichtert aber die Interpretation der Fehlermeldung. Um nicht jedesmal das Prädikat und die Beschreibung neu tippen zu müssen,
kann man beides zu einer Condition
zusammenfassen und irgendwo ablegen. Die kompakteste Definition
sieht zum Beispiel so aus:
Condition<Person> InAbteilungX = new Condition<>(p -> p.abteilung.equals("X"), "ist in X");
Der Aufruf sieht dann im Unit-Test so aus:
Assertions.assertThat(person).is(InAbteilungX);
Conditions lassen sich mit not()
negieren, mit allOf()
-- das entspricht einer und-Verknüpfung --
und mit anyOf()
-- das entspricht einer oder-Verknüpfung -- verbinden.
Für die Erzeugung von Conditions kann man auch Factory-Methoden definieren. Hier wird zu einer Abteilung eine Condition erzeugt, die die Zugehörigkeit einer Person zu einer Abteilung testet:
static Condition<Person> inAbteilung(String abt) { Predicate<Person> pred = p -> p.abteilung.equals(abt); String description = "Abteilung " + abt; return new Condition<Person>(pred, description); }
im Unit-Test sieht der Aufruf damit so aus:
Assertions.assertThat(person).is(inAbteilung("X"));
Ist die Condition nicht erfüllt, erhält man folgende Ausgabe. Für die Ausgabe des Namens ist die
toString
-Methode der Klasse Person
verantwortlich:
java.lang.AssertionError: Expecting: <Kasimir> to have: <Abteilung X>