Hamcrest liefert zwar schon eine Menge an Matchern mit, aber nicht immer findet man das Gewünschte und man benötigt einen eigenen Matcher.
In diesem Beispiel schreiben wir einen Matcher der überprüft ob eine Zeichenkette mit A, B oder C beginnt und darauf drei Zahlen folgen. Da wir diese Prüfung in vielen verschiedenen Unit Tests durchführen müssen, schreiben wir einen eigenen Matcher.
import org.hamcrest.Description; import org.hamcrest.Factory; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; public class IsAbcNumber extends TypeSafeMatcher{ @Override public boolean matchesSafely(String aString) { return aString != null && aString.matches("[A,B,C]\\d{3}"); } public void describeTo(Description description) { description.appendText("not a valid ABC number"); } @Factory public static Matcher abcNumber() { return new IsAbcNumber(); } }
Unser Matcher ist eine Subklasse von TypeSafeMatcher und implementiert die beiden Methoden matchesSafely und describeTo. In machesSafely wird die eigentliche Prüfung durchgeführt und true oder false zurückgegeben. describeTo ist zuständig für den Text der ausgegeben wird wenn die Behauptung nicht zutrifft.
Die statische Methode abcNumber können wir nun in unsere Testklasse importieren und den Matcher benutzen.
import static IsAbcNumber.abcNumber;
import org.junit.Test;
public class MyUnitTest {
@Test
public void testSomething() {
String aNumber = "notvalid";
assertThat(aNumber, is(abcNumber()));
}
}
Die Fehlermeldung zeigt nun genau an wieso die Behauptung nicht zutrifft.
java.lang.AssertionError:
Expected: is not a valid ABC number
got: "notvalid"
Folgender Test dagegen würde anstandslos durchlaufen.
@Test
public void testSomething() {
assertThat("A120", is(abcNumber()));
assertThat("B130", is(abcNumber()));
assertThat("C140", is(abcNumber()));
}
Weitere Links:
Hamcrest Tutorial
Meine vorherigen Blogposts über: Teil 1 und Teil 2