Name

MockLib

Homepage

http://mocklib.sourceforge.net/mocklib3/index.html

Lizenz

Apache License V2.0

Untersuchte Version

JMockLib r3-1-1, February 11, 2009

Letzter Untersuchungszeitpunkt

08.11.2010

Kurzbeschreibung

MockLib erlaubt es Methoden zu testen, die auf noch nicht ausprogrammierte Klassen zugreifen. Hierbei muss die zu testende Methode anstatt einer Klasse ein Interface erwarten. Anstatt einer ausprogrammierten Klasse bekommt sie dann einen mit MockLib zur Laufzeit erstellten Mock untergeschoben. Da dieser Mock natürlich nicht die volle Programmlogik bietet, welche die ausprogrammierte Klasse einmal bieten soll, wird innerhalb des TestCases definiert, wie der Mock auf genau diesen einen Fall reagieren soll. Ebenfalls können die der Mock-Methode übergebenen Parameter abgefragt und überprüft werden, um so nicht nur das Ergebnis der zu testenden Methode, sondern auch den korrekten Methodenaufruf zu prüfen.

Fazit

MockLib ist komplexer zu bedienen, als es zu Beginn den Eindruck macht. Zahlreiche kleine und nur unzureichend dokumentierte Fallstricke machen den Einstieg zäher und langwieriger als es sein müsste. Die gebotene Funktionalität ist dagegen gut. Zwar lassen sich nicht für unterschiedliche Parameter der gleichen Mock-Methode unterschiedliche Werte zurückgeben, was an sich schade ist, doch weiß der restliche Funktionsumfang, wie die abfragbaren Parameter, zu überzeugen. Beim Einsatz in kleinen Projekten muss abgewägt werden, ob es nicht einfacher und schneller ist, die Methode welche fehlt, kurz zu implementieren, anstatt mit einem Mock zu emulieren. In größeren Projekten sollte sich der zusätzliche Zeitaufwand aber schnell rechnen, da hier schon im vorhandenen Code Fehler identifiziert werden können, bevor das ganze Programm fertig ist.

Einsatzgebiete

MockLib kann immer dann eingesetzt werden, wenn eine zu testende Methode auf eine weitere, noch nicht existente Methode, zugreift. Da MockLib nicht nur einen Rückgabewert für den Mock festlegen, sondern auch die übergebenen Parameter ausgeben kann, lassen sich auch Methodenaufrufe auf Korrektheit testen, die keinen Wert zurückgeben.

Einsatzumgebungen

MockLib basiert auf JUnit und kann sich damit in alle Einsatzumgebungen einfügen, in denen auch JUnit arbeiten kann.

Installation

Das Werkzeug benötigt keine Installation. Es muss lediglich das Jar-File heruntergeladen und in den BuildPath eingebunden werden, danach lässt sich MockLib benutzen.

Dokumentation

Die Dokumentation ist die größte Schwachstelle von MockLib. Es existiert schlicht keine. Auf der Projektseite finden sich die JavaDoc API-Doku und ein Satz zugegebenermaßen umfangreicher, kommentierter Beispiele, aber eine echte Anleitung fehlt leider vollständig. So ist man gezwungen, die Beispiele Zeile für Zeile abzuarbeiten, um die hierbei gefundenen Konzepte auf eigenen Code zu übertragen, was nicht immer gut gelingt. Die Kommentare innerhalb der Beispiele sind gerade so umfangreich, dass man nach längerem Studieren des Codes die Funktionsweise erkennen kann. Hier wäre es wesentlich angenehmer gewesen, ein paar Seiten Fließtext zu den Beispielen zu schreiben, welche die Arbeitsweise von MockLib Schritt für Schritt erklären.

Wartung der Projektseite

Die Projektseite hat zumindest mit dem Release der neusten Version ein Update erfahren und scheint auch sonst immer wieder an den Stand der aktuellen Version angepasst zu werden.

Nutzergruppen und Support

Das auf SourceForge gehostete Projekt nutzt die dort angebotenen Funktionen der Mailinglist sowie des Forums. Der Bugtracker ist zwar ebenfalls aktiv, wird aber scheinbar nicht regelmäßig genutzt.

Intuitive Nutzbarkeit

Die intuitive Nutzbarkeit ist einfach nicht gegeben. Die fehlende Doku macht es quasi unmöglich, schnell eine Funktion nachzuschlagen, es muss jedes mal in den Codebeispielen gesucht werden, was mitunter sehr mühsam ist. Auch einzelne konzeptionelle Unschönheiten machen dem Neuanwender das Leben schwer. So ist es z.B. recht seltsam, dass neu erstellte Mocks erst noch zum richtigen Typ hin gecastet werden müssen. Es muss mit einiger Einarbeitungszeit gerechnet werden, bis MockLib produktiv eingesetzt werden kann.

Automatisierung

Da MockLib auf JUnit basiert, kann es in gleichem Umfang automatisiert werden. Dem Einsatz in einem Ant-Skript steht somit nichts im Wege.
ANT
Die Automatisierung von MockLib ähnelt stark der Automatisierung von JUnit-Tests. Da MockLib auch das JUnit-Framework verwendet, müssen keine großen Änderungen vorgenommen werden, falls ein JUnit-Testablauf mit Hilfe von Ant definiert wurde. Zum Kompilieren der Sourcen müssen allerdings weitere externe Bibliotheken eingebunden werden. Dabei handelt es sich um das aktuelle Junit.jar und das aktuelle mocklib.jar. Zu dem verhält sich der Testablauf mit Hilfe des MockLib-Frameworks gleich mit dem Ablauf von normalen JUnit-Tests. Dadurch können die vorhanden Features eines JUnit-Testablaufs wie z. B. die automatische Report Generierung genutzt werden.
Eine Beispielautomatisierung ist hier zu finden.
Maven
Die Automatisierung der Mocklib Testfälle ähnelt stark der Ausführung von JUnit-Testfällen. Der Mocklib-Testfall wird in diesem Szenario durch einen JUnit-Testfall angestoßen und ist somit für den Maven-Prozess nicht direkt relevant. Die Sourcen müssen zwar beim Kompilieren und bei der Ausführung auf die Mocklib-Bibliothek zugreifen, dies ist allerdings leicht mit Hilfe des <dependency>-Elements realisiert. Davor muss die Mocklib-Bibliothek noch in das lokale Repository von Maven übertragen werden. Der folgenden Befehle erledigt diesen Aspekt:
mvn install:install-file -DgroupId=mocklib -DartifactId=mocklib -Dversion=3.0 -Dfile=mocklib3-r3-1-1.jar -Dpackaging=jar -DgeneratePom=true
Hierbei muss sich die Jar-Datei im aktuellen Ordner befinden und die Version ist an die aktuelle Nutzung anzupassen.
Die Ausführung des Tests ähnelt somit stark der Ausführung eines normalen JUnit-Testfalls. Durch den Aufruf mvn test wird der Testfall angestoßen und ausgeführt. Die Ergebnisse lassen sich dann im Target-Verzeichnis finden.
Ein einfaches Automatisierungsbeispiel ist hier zu finden.
Vergleich Ant und Maven
Im Vergleich des Aufwands liegen die beiden build-Werkzeuge circa gleich auf. Bei Maven muss zwar das benötigte JAR-Archiv noch in das lokale Repository gespeichert werden, allerdings ist dieser Aufwand auch nur einmalig da. Die Ausführung der einzelnen Tests wird dann mit Hilfe von JUnit-Testfällen vollzogen und ist somit leicht integrierbar.

Einführendes Beispiel

Zuerst muss ein Mock aus einem gegebenen Interface heraus erstellt werden. Hierbei ist zu beachten, dass die Rückgabe nicht etwa ein Objekt vom Typ des Interfaces ist, sondern ein MockObject, welches erst noch gecastet werden muss.

	pi = MockObjectFactory.createMock(PiAusrechnen.class);

Mit addReturnValue() lässt sich der als String übergebenen Methode ein Rückgabewert zuordnen. Das geschieht nicht in Abhängigkeit von dem übergebenen Parameter. Hier wird leider immer der gleiche Rückgabewert zurückgegeben:

	pi.addReturnValue("calcPi",3.14);

Mit dem gecasteten Mock lässt sich nun die zu testenden Methode aufrufen:

	k.flaeche(10, (PiAusrechnen)pi);

Mit getAllParams() lassen sich alle an die Mock-Methode übergebenen Parameter abfragen und überprüfen:

	Object[] params = pi.expect("calcPi").getAllParams();
	assertEquals(100, params[0]);

Die Klasse MyMocklibTest beinhaltet daraufhin folgenden Code:

	package qsqs.mocklibtest;

	import org.junit.Test;

	import biz.xsoftware.mock.CalledMethod;
	import biz.xsoftware.mock.MockObject;
	import biz.xsoftware.mock.MockObjectFactory;

	import qsqs.ueberdeckungen.Kreis;
	import qsqs.ueberdeckungen.PiAusrechnen;

	import junit.framework.TestCase;

	public class MyMocklibTest extends TestCase {

		private MockObject pi;
		private Kreis k;

		@Override
		protected void setUp() throws Exception {
			pi = MockObjectFactory.createMock(PiAusrechnen.class);
			k=new Kreis();
		}

		@Test
		public void testUmfang() throws Exception {
			pi.addReturnValue("calcPi",3.14);
			assertEquals(10*2*3.14,k.umfang(10, (PiAusrechnen)pi));
			Object[] params = pi.expect("calcPi").getAllParams();
			assertEquals(100, params[0]);
		}

		@Test
		public void testFlaeche() throws Exception {
			pi.addReturnValue("calcPi",3.14);
			assertEquals(10*10*3.14,k.flaeche(10, (PiAusrechnen)pi));
			Object[] params = pi.expect("calcPi").getAllParams();
			assertEquals(1000, params[0]);
		}
	}

Das komplette Beispiel steht ebenfalls als fertiges Eclipse-Projekt zum Download bereit.

Der MockLib-Test kann anschließend als JUnit-Test ausgeführt werden und es öffnet sich die gewohnte JUnit-Ansicht mit den Testergebnissen des Testlaufs:

junit_result


Detaillierte Beschreibung

Nur über Analyse der Beispiele der Webseite möglich.

Literatur

keine

Zurück zur Werkzeugübersicht
Zurück zur CSI-Hauptseite