Die Frage beim Schreiben von Testklassen ist ja, wie sicher gestellt wird, dass eine Applikation umfassend mit Tests abgedeckt ist und mit welchen Mitteln dies getan und überprüft wird. Für TestNG gibt es viele Tutorials und auch konzeptionell birgt es wenig Überraschungen. Mockito andererseits ist mässig dokumentiert und bringt einen komplett anderen Ansatz mit. Deswegen möchte ich hier meine Erkenntnisse zu Mockito zusammenstellen:
Integration von Mockito in Testklassen
Ich bin eigentlich kategorisch gegen statische Imports, da sie den Code unleserlich machen und mit dem Support heutiger IDEs unnötig sind. Bei Testklassen bin ich allerdings zum Schluss gekommen, dass static Imports der Klassen aus dem Testframework zu kompakterem Code führen können und durch die Isolation der Testklassen klar ist, woher die entsprechenden Methoden kommen.
Wann schreibe ich welche Art von Tests?
Bei Klassen, die auf anderen selbstgeschriebenen Klassen basieren, verwende ich primär Mockito um das Verhalten einer Klasse innerhalb ihrem Kontext zu beschreiben und zu testen. Dabei ist es wichtig nur die direkt referenzierten Klassen zu mocken. Für Tests der Importparameter ist TestNG gut geeignet.
Kurz: das Verhalten eines Subsystems oder Methoden mit komplexen Abläufen (if, switch, ...) werden mit Mockito getestet; für alle anderen Tests gibt es TestNG.
Verwendung von Mockito
Mit Mockito lassen sich Klassen und Interfaces mocken (Ausnahme sind statische Klassen und final-deklarierte Klassen). Da es, wie bereits gesagt, kein gute Dokumentation zu Mockito gibt (wer etwas kennt, soll es mir doch bitte zeigen), stelle ich in verschiedenen Artikeln meine Erfahrungen und Erkenntnisse zusammen.
JavaDoc zur Version 1.8.5 ist hier.
Ich fange mit der Klasse Mockito, bzw der Annotation @Mock an:
Beide Varianten dienen dazu eine bestehende Klasse oder ein Interface zu mocken, d.h. mit einer temporären Implementierung zu versehen, die nur während der Gültigkeit des Objekts in Tests ansprechbar ist und deren Methoden nichts tun. In Beispielen sieht man häufig, dass bestehende Java-Klassen gemockt werden. Das ist natürlich nicht praxisnah; normalerweise mockt man eigene Klassen.
Bevor ich auf die >20 statischen Methoden dieser zentralen Klasse in einem separatem Artikel eingehe, möchte ich kurz verwandte Klassen positionieren.
Die Klasse BDDMockito
ist eine Variation von Mockito
. Diese unterstützt Behaviour getriebene Entwicklung; damit ist gemeint, dass die Klasse den Use-Case des Kunden präzis und nahe seiner Sprache abbildet. Beim Durchführen der Tests wird geprüft, ob das gewünschte Verhalten abgebildet wird.
Die Annotation @Captor
scheint für einen bestimmten Testcase ausgelegt zu sein, den ich aber noch nicht verstanden habe.
Eine weitere Annotation in diesem Zusammenhang ist @Spy
. Dies lässt sich auch mit Mockito.spy(...)
abbilden. Diese Funktionalität ermöglicht es ledigliche Teile von Klassen zu mocken, während andere 'normal' laufen. Bei Klassen, die nur statische Methoden enthalten, kann das funktionieren. Sinn macht es wohl nur in sehr sepezielle Fällen. Besser ist's wohl @Spy
zu vergessen.