Was ist das beste Framework zum Erstellen von Scheinobjekten in Java? Warum? Was sind die Vor- und Nachteile der einzelnen Frameworks?
Was ist das beste Framework zum Erstellen von Scheinobjekten in Java? Warum? Was sind die Vor- und Nachteile der einzelnen Frameworks?
Antworten:
Ich habe gute Erfolge mit Mockito erzielt .
Als ich versuchte, etwas über JMock und EasyMock zu lernen, fand ich die Lernkurve etwas steil (obwohl ich das vielleicht nur bin).
Ich mag Mockito wegen seiner einfachen und sauberen Syntax, die ich ziemlich schnell verstehen konnte. Die minimale Syntax wurde entwickelt, um die gängigen Fälle sehr gut zu unterstützen, obwohl die wenigen Male, die ich etwas Komplizierteres tun musste, fanden, dass das, was ich wollte, unterstützt und leicht zu verstehen war.
Hier ist ein (gekürztes) Beispiel von der Mockito-Homepage:
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
Einfacher geht es nicht.
Der einzige große Nachteil, den ich mir vorstellen kann, ist, dass statische Methoden nicht verspottet werden.
Ich bin der Schöpfer von PowerMock, also muss ich das natürlich empfehlen! :-)
PowerMock erweitert sowohl EasyMock als auch Mockito um die Möglichkeit, statische Methoden , endgültige und sogar private Methoden zu verspotten . Die EasyMock-Unterstützung ist vollständig, aber das Mockito-Plugin benötigt noch etwas Arbeit. Wir planen, auch JMock-Unterstützung hinzuzufügen.
PowerMock soll andere Frameworks nicht ersetzen, sondern kann in schwierigen Situationen verwendet werden, in denen andere Frameworks keine Verspottung zulassen. PowerMock enthält auch andere nützliche Funktionen wie das Unterdrücken statischer Initialisierer und Konstruktoren.
Die JMockit-Projektwebsite enthält zahlreiche Vergleichsinformationen für aktuelle Verspottungs-Toolkits.
Schauen Sie sich insbesondere die Funktionsvergleichsmatrix an , die EasyMock, jMock, Mockito, Unitils Mock, PowerMock und natürlich JMockit umfasst. Ich versuche es so genau wie möglich zu halten.
Ich habe Erfolg mit JMockit gehabt .
Es ist ziemlich neu und daher etwas roh und unterdokumentiert. Es verwendet ASM , um den Klassenbytecode dynamisch neu zu definieren, sodass alle Methoden verspottet werden können, einschließlich statischer, privater, Konstruktoren und statischer Initialisierer. Zum Beispiel:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
Es verfügt über eine Expectations-Oberfläche, die auch Aufnahme- / Wiedergabeszenarien ermöglicht:
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
Der Nachteil ist, dass Java 5/6 erforderlich ist.
Sie können sich auch das Testen mit Groovy ansehen. In Groovy können Sie Java-Schnittstellen einfach mit dem Operator 'as' verspotten:
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
Abgesehen von dieser Grundfunktionalität bietet Groovy viel mehr auf spöttischer Ebene, einschließlich der leistungsstarken MockFor
und StubFor
Klassen.
Ich habe angefangen, Mocks mit EasyMock zu verwenden . Leicht zu verstehen, aber der Wiederholungsschritt war irgendwie nervig. Mockito entfernt dies und hat auch eine sauberere Syntax, da es so aussieht, als ob Lesbarkeit eines seiner Hauptziele war. Ich kann nicht genug betonen, wie wichtig dies ist, da die meisten Entwickler ihre Zeit damit verbringen werden, vorhandenen Code zu lesen und zu pflegen, ohne ihn zu erstellen.
Eine weitere nette Sache ist, dass Schnittstellen und Implementierungsklassen auf die gleiche Weise behandelt werden, anders als in EasyMock, wo Sie sich immer noch merken (und überprüfen) müssen, um eine EasyMock-Klassenerweiterung zu verwenden.
Ich habe mir JMockit kürzlich kurz angesehen, und obwohl die Liste der Funktionen ziemlich umfangreich ist, denke ich, dass der Preis dafür die Lesbarkeit des resultierenden Codes ist und dass mehr geschrieben werden muss.
Für mich ist Mockito genau das Richtige, da es einfach zu schreiben und zu lesen ist und sich mit den meisten Situationen befasst, die der meiste Code erfordert. Die Verwendung von Mockito mit PowerMock wäre meine Wahl.
Eine zu berücksichtigende Sache ist, dass das Tool, das Sie wählen würden, wenn Sie selbst oder in einem kleinen, engmaschigen Team entwickeln würden, möglicherweise nicht das beste für ein großes Unternehmen mit Entwicklern unterschiedlicher Fähigkeiten ist. Lesbarkeit, Benutzerfreundlichkeit und Einfachheit müssten im letzteren Fall stärker berücksichtigt werden. Es macht keinen Sinn, das ultimative Spott-Framework zu erhalten, wenn viele Leute es nicht verwenden oder die Tests nicht beibehalten.
Wir verwenden EasyMock und EasyMock Class Extension häufig bei der Arbeit und sind ziemlich zufrieden damit. Es gibt Ihnen im Grunde alles, was Sie brauchen. Schauen Sie sich die Dokumentation an, es gibt ein sehr schönes Beispiel, das Ihnen alle Funktionen von EasyMock zeigt.
Ich habe JMock früh benutzt. Ich habe Mockito bei meinem letzten Projekt ausprobiert und es hat mir gefallen. Prägnanter, sauberer. PowerMock deckt alle Anforderungen ab, die in Mockito fehlen, z. B. das Verspotten eines statischen Codes, das Verspotten einer Instanzerstellung, das Verspotten der endgültigen Klassen und Methoden. Ich habe also alles, was ich brauche, um meine Arbeit auszuführen.
Ich mag JMock, weil Sie Erwartungen aufstellen können. Dies unterscheidet sich grundlegend von der Überprüfung, ob eine Methode aufgerufen wurde, die in einigen Scheinbibliotheken gefunden wurde. Mit JMock können Sie sehr anspruchsvolle Erwartungen schreiben. Siehe den Jmock Cheat-Sheat .
Ja, Mockito ist ein großartiger Rahmen. Ich benutze es zusammen mit Hamcrest und Google Guice, um meine Tests einzurichten .
Die beste Lösung für das Verspotten besteht darin, dass die Maschine die gesamte Arbeit mit automatisierten spezifikationsbasierten Tests erledigt. Informationen zu Java finden Sie unter ScalaCheck und das in der Functional Java- Bibliothek enthaltene Reductio- Framework . Mit automatisierten spezifikationsbasierten Testframeworks geben Sie eine Spezifikation der zu testenden Methode an (eine Eigenschaft, die wahr sein sollte), und das Framework generiert automatisch Tests sowie Scheinobjekte.
Die folgende Eigenschaft testet beispielsweise die Math.sqrt-Methode, um festzustellen, ob die Quadratwurzel einer positiven Zahl n im Quadrat gleich n ist.
val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }
Wenn Sie aufrufen propSqrt.check()
, generiert ScalaCheck Hunderte von Ganzzahlen und überprüft Ihre Eigenschaft für jede Ganzzahl. Außerdem wird automatisch sichergestellt, dass die Randfälle gut abgedeckt sind.
Obwohl ScalaCheck in Scala geschrieben ist und den Scala-Compiler benötigt, ist es einfach, Java-Code damit zu testen. Das Reductio-Framework in Functional Java ist eine reine Java-Implementierung derselben Konzepte.
Mockito bietet auch die Möglichkeit, Methoden zu stubben, Argumente (wie anyInt () und anyString ()) abzugleichen, die Anzahl der Aufrufe (times (3), atLeastOnce (), never ()) und mehr zu überprüfen .
Ich habe auch festgestellt, dass Mockito einfach und sauber ist .
Eine Sache, die ich an Mockito nicht mag, ist, dass man statische Methoden nicht stoppen kann .
Für etwas anderes könnten Sie JRuby und Mocha verwenden, die in JtestR kombiniert werden , um Tests für Ihren Java-Code in ausdrucksstarkem und prägnantem Ruby zu schreiben. Es gibt einige nützliche spöttischen Beispiele mit JtestR hier . Ein Vorteil dieses Ansatzes besteht darin, dass das Verspotten konkreter Klassen sehr einfach ist.
Ich habe angefangen, Mocks über JMock zu verwenden, bin aber schließlich auf EasyMock umgestiegen. EasyMock war genau das - einfacher - und lieferte eine Syntax, die sich natürlicher anfühlte. Ich habe seitdem nicht mehr gewechselt.