Artikelformat

Mockito Magie

Wer Unittests schreibt, weiß wie praktisch Mock-Objekte und die Frameworks sind, die diese zur Verfügung stellen. Heute konnte ich im Mockito-Java Umfeld etwas interessantes von einem Kollegen lernen und gebe das gerne weiter.

Mockito ist schon an sich ein sehr geniales Framework und es macht immer wieder Spaß verify zu benutzen. Mit dieser Funktion kann man überprüfen, ob eine Methode eines Mock-Objekts aufgerufen wurde. Selbstverständlich kann man diesen Aufurf noch genauer spezifizieren. Beispielsweise geht auch das Gegenteil – also wurde die Methode nicht aufgerufen. Oder man überprüft, ob diese x-mal aufgerufen wurde. Das liegt alles im Ermessen des Programmierers und wird dann sinnvoll eingesetzt.

Der wichtige Punkt ist, das man die Parameter einer Methode angeben muss. Man kann entweder einen festen Wert (oder genauer Objekt) angeben, oder einen Matcher nutzen. Matcher erlauben eine gewisse Varianz. Es ist somit möglich zu überprüfen, ob als Parameter eine Klasse des Typs Foo benutzt wurde. Ob das Objekt als valide Eingabe akzeptiert wird, hängt von der Implementierung des Matchers ab.
Nur der Sinn des Tests und die Lesbarkeit sind die Grenze dessen was man machen kann.

Richtig spannend ist der ArgumentCaptor. Dieser erlaubt es dem Entwickler einen allgemeingültigen Matcher für eine Klasse implizit zu definieren und man erhält auch noch Zugang zum eigentlichen Objekt. D.h. wenn ich wie im unten angeführten Beispiel weiß, dass meine UI im Test ein ResizeEvent feuert und ich den genauen Inhalt des Events benötige, ist der ArgumentCaptor genau die richtige Art und Weise, um den Inhalt relativ leicht zu bekommen.

ArgumentCaptor<ResizeEvent> resizeEventCaptor 
   = ArgumentCaptor.forClass(ResizeEvent.class);
Mockito.verify(eventBusMock)
   .fireEvent(resizeEventCaptor.capture());
Assert.assertEquals(testPresenter.getMaxW(), 
   resizeEventCaptor.getValue().getWidth());

In der ersten Zeile wird programmatisch der Captor erzeugt. Dessen capture Methode geben wir als Matcher an und nutzen verify wie wir es gewohnt sind. Da wir auf static-Imports verzichten ist der Aufruf etwas umständlich Mockito.verify. Danach kann man mit assertEquals den Inhalt des Captor-Werts vergleichen. Da der Captor mit Generics arbeitet kann man sich das Casting sparen.

Als kleine Ergänzung kann man statt des programmatischen Aufrufs auch mit Annotationen arbeiten. Dann gibt man @Captor an und schon wird das Attribut in einen Captor verwandelt. Man sollte hierbei nicht die Verarbeitung der Annotationen vergessen wie man sie von @Mock kennt.

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.