Ich habe hier einige Threads über statische Methoden gelesen und denke, ich verstehe die Probleme, die Missbrauch / übermäßiger Gebrauch statischer Methoden verursachen können. Aber ich bin nicht wirklich auf den Grund gegangen, warum es schwierig ist, statische Methoden zu verspotten.
Ich weiß, dass andere spöttische Frameworks wie PowerMock das können, aber warum kann Mockito das nicht?
Ich habe diesen Artikel gelesen , aber der Autor scheint religiös gegen das Wort zu sein static
, vielleicht ist es mein schlechtes Verständnis.
Eine einfache Erklärung / Link wäre toll.
Antworten:
Ich denke, der Grund könnte sein, dass Scheinobjektbibliotheken normalerweise Mocks erstellen, indem sie zur Laufzeit dynamisch Klassen erstellen (mit cglib ). Dies bedeutet, dass sie entweder zur Laufzeit eine Schnittstelle implementieren (das macht EasyMock, wenn ich mich nicht irre), oder sie erben von der Klasse zum Verspotten (das macht Mockito, wenn ich mich nicht irre). Beide Ansätze funktionieren nicht für statische Elemente, da Sie sie nicht mithilfe der Vererbung überschreiben können.
Die einzige Möglichkeit, die Statik zu verspotten, besteht darin , den Bytecode einer Klasse zur Laufzeit zu ändern , was vermutlich etwas aufwendiger ist als die Vererbung.
Das ist meine Vermutung, für was es wert ist ...
quelle
Wenn Sie eine statische Methode verspotten müssen, ist dies ein starker Indikator für ein schlechtes Design. Normalerweise verspotten Sie die Abhängigkeit Ihrer zu testenden Klasse. Wenn sich Ihre zu testende Klasse auf eine statische Methode bezieht, wie z. B. java.util.Math # sin, bedeutet dies, dass die zu testende Klasse genau diese Implementierung benötigt (z. B. Genauigkeit vs. Geschwindigkeit). Wenn Sie von einer konkreten Sinus-Implementierung abstrahieren möchten, benötigen Sie wahrscheinlich eine Schnittstelle (sehen Sie, wohin diese führen wird)?
quelle
Ich denke ernsthaft, dass es Code-Geruch ist, wenn Sie auch statische Methoden verspotten müssen.
Das einzige Mal, dass mir das übertrieben erscheint, sind Bibliotheken wie Guava, aber Sie sollten diese Art sowieso nicht verspotten müssen, weil sie Teil der Logik ist ... (Sachen wie Iterables.transform (..)) Auf
diese Weise Ihr eigener Code bleibt sauber, Sie können alle Ihre Abhängigkeiten auf saubere Weise verspotten und Sie haben eine Antikorruptionsschicht gegen externe Abhängigkeiten. Ich habe PowerMock in der Praxis gesehen und alle Klassen, für die wir es brauchten, waren schlecht gestaltet. Auch die Integration von PowerMock verursachte zeitweise schwerwiegende Probleme
(z. B. https://code.google.com/p/powermock/issues/detail?id=355) ).
PS: Gleiches gilt auch für private Methoden. Ich denke nicht, dass Tests über die Details privater Methoden Bescheid wissen sollten. Wenn eine Klasse so komplex ist, dass sie versucht, private Methoden zu verspotten, ist dies wahrscheinlich ein Zeichen, um diese Klasse aufzuteilen ...
quelle
@Inject SomeDependency
und in meiner Konfiguration definiere ichbind(SomeDependency.class).in(Singleton.class)
. Wenn es also morgen kein Singleton mehr ist, ändere ich die eine Konfiguration und das wars.Foo.getInstance()
überall anruft . Ich habe gerade Singleton in die Antwort geschrieben, um dem Argument entgegenzuwirken, "aber eine statische Methode erfordert nicht die Erstellung vieler Wrapper-Objekte". Auch konzeptionell gibt es für mich kaum einen Unterschied zwischen einer statischen Methode und einer Instanzmethode für einen Singleton, nur dass Sie diesen Singleton-Kollaborateur nicht verspotten können. Aber Singleton oder nicht ist absolut nicht der Punkt, den ich anstrebte. Es geht darum, Kollaborateure zu injizieren und zu verspotten und keine statischen Methoden aufzurufen, wenn dies das Testen erschwert.Mockito gibt Objekte zurück, aber statisch bedeutet "Klassenebene, nicht Objektebene". Mockito gibt also eine Nullzeigerausnahme für statisch.
quelle
In einigen Fällen kann es schwierig sein, statische Methoden zu testen, insbesondere wenn sie verspottet werden müssen, weshalb die meisten verspotteten Frameworks sie nicht unterstützen. Ich fand diesen Blog-Beitrag sehr nützlich, um zu bestimmen, wie man statische Methoden und Klassen verspottet.
quelle