Was ist das beste Mock-Framework für Java? [geschlossen]

347

Was ist das beste Framework zum Erstellen von Scheinobjekten in Java? Warum? Was sind die Vor- und Nachteile der einzelnen Frameworks?

Josh Brown
quelle

Antworten:

315

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.

Brian Laframboise
quelle
15
Wunderschönen. Kombinieren Sie für statische Methoden einfach Mockito mit JMockit, und es gibt praktisch keine Klasse, die zu "Legacy" ist, als dass Sie sie testen könnten.
Epaga
6
Ich finde es toll, dass Sie, wenn Sie versuchen, etwas zu tun, das Sie nicht tun sollten (z. B. Mocks inline erstellen), eine sehr klare Erklärung dafür erhalten, was Sie in der Ausnahmemeldung falsch gemacht haben.
Ripper234
3
Für mich absolut. Ich würde es trotzdem bedingungslos empfehlen. Wenn Sie ein anderes Framework finden, das Ihren Anforderungen besser entspricht, erwähnen Sie es natürlich in einer anderen Antwort und sehen Sie, welche Stimmen es erhält und welche Arten von Kommentaren es erhält.
Brian Laframboise
2
@MexicanHacker warum kannst du es nicht für Android verwenden? Ich benutze es gerade mit Robolectric.
Ilkka
2
Ich benutze Mockito und liebe es !! Tolle Dokumentation (so selten, dass wir eine Dokumentation dieser Qualität finden, gute Arbeit von den Autoren), die für uns so wichtig ist, um Dinge zu verwenden, ohne in den Code des Frameworks eintauchen zu müssen !!!
Renato
84

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.

Jan Kronquist
quelle
Powermock ist wichtig für Unit-Tests von Android-Anwendungen mit nativem Java auf dem Host-PC (Vermeidung der Verwendung des langsamen Emulators)
Jeff Axelrod
@Jan einziges Problem ist, dass PowerMock bei Verwendung von Robolectric nicht kompatibel ist :-( Ich möchte @RunWith (PowerMockRunner.class) UND @RunWith (RobolectricTestRunner.class) ausführen
Blundell
Nachdem ich PowerMock in den letzten Monaten verwendet habe, kann ich es nur empfehlen!
cwash
PowerMock ist wirklich großartig. Ich liebe statische Singletons wirklich, um auf alles zuzugreifen, und dies ermöglicht das Testen.
Ian Macalinao
Vorsichtsmaßnahme: Einige Dinge wie das Verspotten endgültiger Methoden sind nur in Powermock für EasyMock und nicht für Mockito möglich. Es ist ein bisschen gotcha, wenn Sie es nicht so häufig verwenden. Ich habe mich gefragt, warum etwas nicht funktioniert, als mir klar wurde, dass es nur im Abschnitt Easymock des Dokuments aufgeführt ist.
trafalmadorian
46

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.

Rogério
quelle
1
Ich bin beeindruckt von JMockit, es hat eine steilere Lernkurve, aber es hat jahrelang eine sehr gute Dokumentation und es kann alles verspotten. Ich habe mit Mockito angefangen, was leicht zu lernen war, aber ich bin regelmäßig auf Probleme gestoßen, die ich damit nicht lösen konnte. Andererseits kann ich mir nicht einmal vorstellen, was mit JMockit unmöglich ist.
Hontvári Levente
21

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.

Kris Pruden
quelle
Ja, kann das wirklich empfehlen
Epaga
7
Nur ein Update: Das JMockit-Projekt wurde auf code.google.com/p/jmockit verschoben . Es hat sich seit diesem Beitrag VIEL weiterentwickelt (und entwickelt sich immer noch weiter) und verfügt nun über eine umfangreiche Dokumentation.
Rogério
JMockit ist wieder umgezogen. Es ist jetzt bei Github erhältlich. jmockit.github.io
Ravi Thapliyal
15

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 MockForund StubForKlassen.

http://docs.codehaus.org/display/GROOVY/Groovy+Mocks

p3t0r
quelle
13

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.

Trafalmadorianer
quelle
1
+1 Diese Antwort benötigt mehr Upvotes. Man sollte mitteilen, was ihnen am Framework wirklich gefallen hat oder nicht. Nur "Ich habe das benutzt ... und es hat mir gefallen!" ist einer der Gründe, warum so gute Fragen auf SO geschlossen werden.
Ravi Thapliyal
11

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.

Dlinsin
quelle
1
In meiner Frage habe ich mehr nach dem gesucht, was Sie an einem Schein-Framework mögen und was nicht. Ich kann die Dokumentation finden und alles darüber lesen - ich möchte wissen, was die Leute, die sie benutzt haben, darüber denken.
Josh Brown
EasyMock funktioniert nur unter Java 5 und höher, argh!
Matt B
8

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.

Dmitry
quelle
6

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 .

Andrea Francia
quelle
5

Ja, Mockito ist ein großartiger Rahmen. Ich benutze es zusammen mit Hamcrest und Google Guice, um meine Tests einzurichten .

Bartosz Bierkowski
quelle
4

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.

Apocalisp
quelle
3

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 .

Josh Brown
quelle
Diese Antwort ist ungenau. Sie sind nicht auf Schnittstellen mit jMock beschränkt. Mit dem ClassImposteriser können Sie konkrete Klassen verspotten.
Teflon Ted
Mit EasyMock können Sie genau das Gleiche tun.
Cem Catikkas
Ich habe die Ungenauigkeiten aus meiner Antwort entfernt.
Josh Brown
2

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.

James Mead
quelle
1

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.

Mike Furtak
quelle