JUnit 4.4Junit 4.4 ist bereits seit über einem halben Jahr verfügbar. Von den Projekten, die ich kenne, arbeiten viele aber noch mit JUnit 4.0 oder noch älter. Grund genug, einmal ein unscheinbar daher kommendes neues Feature zu betrachten.
assertThatZunächst gibt es eine neue assert-Methode namens
assertThat. assertThat bekommt zwei Parameter übergeben, den tatsächlichen Wert (im Gegensatz zu assertEquals als ersten Parameter) und einen Matcher. Über die Matcher wird letztlich die zu testende Bedingung ausgedrückt.
Aus
assertEquals(10, list.size());
wird
import static org.hamcrest.core.Is.is;
...
assertThat(list.size(), is(10));
Diese Art der Notation geht in Richtung
Fluent-Interface und ist aus meiner Sicht etwas besser lesbar als die klassische Notation.
Zusätzlich zu
is() sind weitere Matcher verfügbar, so dass man im Wesentlichen mit
assertThat auskommen sollte und die meisten anderen assert-Methoden nicht mehr braucht.
Ausdrucksstärker mit HancrestDie
assertThat-Notation geht auf
Hamcrest zurück. In JUnit 4.4 ist ein Teil davon enthalten - warum man da so halbe Sachen gemacht hat, erschließt sich mir nicht. Wenn man
assertThat verwenden möchte, empfiehlt es sich aus meiner Sicht, Hamcrest komplett mit einzubinden. Dann hat man mächtige Matcher zur Verfügung, die die Tests nicht nur lesbarer, sondern auch kürzer gestalten. Möchte ich z.B. den Inhalt einer Liste testen, ist das mit Hamcrest ein Einzeiler:
import static org.hamcrest.Matchers.*;)
...
assertThat(list, hasItems("a", "b", "c"));
Bessere FehlermeldungenNicht zuletzt generiert Hancrest bei fehlschlagenden Tests Fehlermeldungen, die häufig aussagekräftiger sind als bei JUnit-Classic. Bei JUnit-Classic war man außerhalb von
assertEquals auf
assertTrue oder
assertFalse angewiesen und hat dann nur die Meldung bekommen, dass der Test fehlgeschlagen war. Die Gründe dafür konnte man in der Meldung aber nicht erkennen. Hamcrest hingegen generiert aus dem kompletten Matcher eine aussagekräftige Fehlermeldung:
assertThat(foo, anyOf(is(1), is(3)));
prüft, dass das
foo den Wert 1 oder 3 hat (man möge mir das schwache Beispiel verzeihen). Wenn das nicht der Fall ist, erhalten wir in JUnit eine aussagekräftige Fehlermeldung:
java.lang.AssertionError:
Expected: (is <1> or is <3>)
got: <2>
FazitDas
assertThat-Feature kommt etwas unscheinbar daher. Ich finde, dass dem Feature mehr Ehre gebührt und dass es in der Praxis einen größeren positiven Effekt hat, als man zunächst meinen möchte.
Post bewerten