Name

EasyMock

Homepage

http://www.easymock.org/

Lizenz

MIT License

Untersuchte Version

Version 2.4 mit JUnit 4.4

Letzter Untersuchungszeitpunkt

08.11.2010

Kurzbeschreibung

EasyMock 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 EasyMock zur Laufzeit erstellten Mock untergeschoben. Da dieser Mock natürlich nicht die volle Programmlogik bietet, welche die ausprogrammierte Klasse später einmal bieten soll, wird innerhalb des TestCases definiert, wie der Mock auf genau diesen einen Fall reagieren soll. Ebenfalls lässt sich mit EasyMock testen, ob der Aufruf der Mockmethode überhaupt stattgefunden hat, so dass hier schon Programmierfehler aufgespürt werden können.

Fazit

EasyMock hält was der Name verspricht: Ein einfach zu nutzendes Werkzeug zur Erstellung von Mocks. Der Funktionsumfang beschränkt sich hierbei auf die Kernkompetenzen ohne unnötiges Beiwerk. Durch die gute Doku und das einfache und durchgängig umgesetzte Konzept geht der Einstieg schnell von statten. Für den Einsatz in kleinen Projekten bleibt aber abzuwägen, ob wirklich ein Mock-Werkzeug zum Einsatz kommen muss. Hier kann es eventuell schneller sein, einfach die fehlende Methode/Klasse zu implementieren, als einen Test über einen Mock zu verwirklichen. Für große Projekte mit vielen Entwicklern und eventuell sogar einer eigenen Mannschaft, die sich nur um das Qualitätsmanagement kümmert ist EasyMock dagegen wie geschaffen. Mit JUnit als Basis skaliert es auch für große Projekte sehr gut und kann ohne größere Umstände in schon vorhandene Projekte eingebunden werden. Die Aktualität sorgt dabei für eine hohe Kompatibilität zu aktuellen Entwicklungswerkzeugen.

Einsatzgebiete

EasyMock kann immer dort zum Einsatz kommen wo Klassen/Methoden zum Test von anderen Klassen/Methoden benötigt werden, welche aber noch nicht fertig ausprogrammiert sind. Dabei ist es egal, ob es sich um funktionelle Klassen, welche ein Ergebnis berechnen, oder um Bestandteile einer GUI handelt.

Einsatzumgebungen

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

Installation

EasyMock muss nicht speziell installiert werden. Es genügt, das Java-Archiv herunter zu laden, zu entpacken und die Bibliothek "easymock.jar" in den Buildpath der jeweiligen IDE hinzuzufügen. Zusätzlich wird eventuell noch JUnit 4.x benötigt, welches hier gefunden werden kann und ebenfalls in den Buildpath integriert werden muss.

Eclipse: Projekt -> Properties -> Java Build Path -> Add external Jar -> easymock.jar auswählen
Netbeans: Projekt -> Properties -> Libraries -> Add Jar -> easymock.jar auswählen

Dokumentation

Die Dokumentation von EasyMock ist neben Englisch auch in Französisch vorhanden in zwei Teile untergliedert, die Anwenderdokumentation, welche als Fließtext vorliegt und anhand vieler Beispiele die Nutzung von EasyMock erklärt, sowie die JavaDoc API Dokumentation, welche nur in Englisch verfügbar ist.
Die Anwenderdokumentation ist leicht verständlich, setzt aber Grundwissen im Bereich JUnit und Softwarequalität voraus. Die Beispiele sind gut und erklären einfach und verständlich, wie das Werkzeug zu benutzen ist. Der einzige Kritikpunkt ist, dass die in den Beispielen verwendeten Klassen- und Methodennamen zum Teil verlauten lassen, dass sie Teil der Libary sind, obwohl sie zum Test gehören.
Die API Dokumentation ist leider nicht so gut gelungen wie die Anwenderdokumentation. Es gibt noch etliche Methoden, zu denen kein JavaDoc existiert. Hier wäre es besser gewesen, wenn man sich direkt in der benutzten IDE anzeigen lassen könnte, welche Funktionalität die Methode bietet und was diese erwartet. Da sich das Werkzeug noch in der Weiterentwicklung befindet, kann sich dieser Punkt durchaus noch bessern.

Wartung der Projektseite

Die Projektseite ist vom Juli 2008 und damit zusammen mit der letzten Aktualisierung von EasyMock erschienen. Das Projekt scheint sich noch in Entwicklung zu befinden, was darauf hoffen lässt, dass es auch noch an kommende Versionen von Java und JUnit angepasst wird.

Nutzergruppen und Support

Das Projekt bietet dem Nutzer eine Yahoo!Group, über welche Kontakt mit den Entwicklern aufgenommen werden kann. Obwohl das Projekt bei SourceForge gehostet ist, werden die SourceForge-Funktionalitäten wie Mailinglist oder Forum nicht genutzt. Der Bugtracker ist zwar aktiv, allerdings wird er von den Entwicklern ebenfalls nicht genutzt.

Intuitive Nutzbarkeit

Die Einarbeitung in EasyMock geht nicht zuletzt wegen der guten und beispielreichen Dokumentation schnell von Statten. In wenigen Minuten hat man die Funktionsweise begriffen und ist in der Lage, das Werkzeug im Projektumfeld einzusetzen. Dass die Methoden tun was ihr Name verspricht, beschleunigt die Einarbeitung nochmals.

Automatisierung

Da EasyMock in JUnit-Testfällen zum Einsatz kommt, kann es von der umfangreichen Automatisierung von JUnit profitieren. Die Integration ist dadurch genauso gegeben wie der Einsatz in einem Ant-Skript.
ANT
Die Automatisierung von EasyMock ähnelt stark der Automatisierung von JUnit-Tests. Da EasyMock 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. Zur Vollständigkeit sei diesen nochmal aufgelistet: Zu dem verhält sich der Testablauf mit Hilfe des EasyMock-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 EasyMock Testfälle ähnelt stark der Ausführung von JUnit-Testfällen. Der EasyMock-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 EasyMock-Bibliotheken zugreifen, dies ist allerdings leicht mit Hilfe des <dependency>-Elements realisiert. EasyMock bietet ein fertiges Plugin zur Einbindung in das Maven-Skript an. Dazu muss die pom.xml nur um das folgende Dependency-Element erweitert werden:
	<dependency>
		<groupId>org.easymock</groupId>
		<artifactId>easymock</artifactId>
		<version>3.0</version>
	</dependency>
Die benötigten EasyMock-Bibliotheken werden dann automatisch von dem Maven-Repository heruntergeladen.
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
Der Aufwand der beiden build-Werkzeuge ist circa der gleiche. Maven bietet schon ein fertiges Plugin das über das dependency-Element leicht eingebunden werden kann. Bei Ant müssen die benötigten Jar-Archive manuell eingebunden werden. Allerdings bietet Ant hingegen wiederum die Verwendung von Pattern-Sets an. Diese ermöglichen dem Benutzer zum Beispiel alle Dateien aus einem bestimmten Ordner mit einzubinden. Dadurch sinkt der manuelle Aufwand von Ant wiederum.

Einführendes Beispiel

Ziel des einführenden Beispiels ist es, die Funktions- und Implementationsweise von Mocks anhand eines einfachen und leicht nachvollziehbaren Beispiels aufzuzeigen.

Zur sinnvollen Verwendung von Mocks wird ein Interface benötigt, dessen Methoden noch implementiert werden müssen. Dazu wird in diesem Beispiel das Interface IMockMe genutzt, welches den Rückgabwert von Pi bis zu einer der Funktion übergegeben Genauigkeit und die Bearbeitung eines Strings bereitstellt:

public interface IMockMe {

	public double Pi(int precision);
	public void addString(String addMe);

}

Nun wird eine Klasse benötigt, welche auf die Methoden des Interfaces zurückgreift:

public class MockMeImplemented{

	/* Benutzt die nicht implementierte Interfacemethode addString(String addMe); */
	public void addStringtoList(String addMe,IMockMe pie){
		pie.addString(addMe);
	}

	/* Benutzt die nicht implementierte Interfacemethode Pi(int precision); */
	public double returnPI(int precision,IMockMe pi){
			return pi.Pi(precision);
	}
}

Da EasyMock hauptsächlich auf statische Methoden setzt, muss zu Beginn das Paket entsprechend eingebunden werden:

import static org.easymock.EasyMock.*;

Zur Durchführung der Tests wird jeweils ein Objekt von MockMeImplemented und IMockMe benötigt.
Nach der Erstellung muss dem Interface mittels mock = createMock(IMockMe.class); ein Mock zugewiesen werden.

	private IMockMe mock;
	private MockMeImplemented piImp;

	@Before
	public void setUp(){

		mock = createMock(IMockMe.class);
		piImp = new MockMeImplemented();

	}

Nach der Erstellung des Mocks folgt die Aufnahme und Wiedergabe des Testverhaltens.
Die Aufnahme erfolgt bis zum Aufruf der Methode replay();. So wird in folgendem Codeausschnitt der Aufruf der Interfacemethode mock.addString("i"); aufgenommen und mittels replay(mock); wiedergegeben.
Nach dem Umschalten in den Wiedergabemodus kann überprüft werden, ob das Verhalten von addStingtoList korrekt ist.
Zudem wird automatisch geprüft, ob die Übergabeparameter mit denen der "gemockten" Methode übereinstimmen. verify(mock); stellt sicher, dass die angegeben Methoden auch tatsächlich ausgeführt wurden:

	@Test
	public void expectedAddSomethig(){

		mock.addString("i");
		replay(mock);
		piImp.addStringtoList("i", mock);
		verify(mock);
	}

Wird verify(mock); nicht verwendet, würde auch dieser Fall den Testdurchlauf bestehen:

	@Test
	public void expectedAddSomethig2(){

		mock.addString("i");
		replay(mock);

	}

In diesem Fall wird die Mockfunktionalität mit JUnit kombiniert, um den Rückgabewert von piImp.returnPI(); zu überprüfen. Mit expect(mock.Pi(100)).andReturn((double)3.14); wird angegeben, welcher Wert von der Methode Pi(); zurückgegeben werden soll. Da returnPI(); die unimplementierte Methode Pi(); aufruft, wird der übergebene Wert des Mocks verwendet. Durch assertEquals(); wird getestet, ob der erwartete Wert mit dem tatsächlichen Wert übereinstimmt.

	@Test
	public void expectedValuePi(){

		expect(mock.Pi(100)).andReturn((double)3.14);
		replay(mock);
		assertEquals(3.14, piImp.returnPI(100,mock), 0);
		verify(mock);

	}

Die geschriebenen Testfälle lassen sich einfach über Rechtsklick auf die Testklasse -> Run as -> JUnit ausführen. Die Auswertung folgt nach dem bekannten JUnit-Stil. Grüne Testfälle zeigen bestandene, rot markierte Testfälle nicht bestandene Tests. Zudem wird ein "Failure Trace" angezeigt, dem genauere Informationen über den Testfehlschlag entnommen werden können. In diesem Fall wurde der Methodenaufruf Pi(); mit einem unerwarteten Parameter aufgerufen.

easymock_result

Das komplette Beispiel steht ebenfalls zum Download bereit: [EasyMock-Test.tar.gz]

Detaillierte Beschreibung

Die EasyMock-Dokumentation auf der Projektseite.

Literatur

keine

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