Ich bin neu in Mockito.
Wie kann ich in der folgenden Klasse mit Mockito überprüfen, ob someMethod
genau einmal aufgerufen wurde, nachdem foo
es aufgerufen wurde?
public class Foo
{
public void foo(){
Bar bar = new Bar();
bar.someMethod();
}
}
Ich möchte den folgenden Bestätigungsaufruf tätigen:
verify(bar, times(1)).someMethod();
Wo bar
ist eine verspottete Instanz von Bar
.
Antworten:
Abhängigkeitsspritze
Wenn Sie die Bar-Instanz oder eine Factory einfügen, die zum Erstellen der Bar-Instanz verwendet wird (oder eine der anderen 483 Möglichkeiten, dies zu tun), haben Sie den erforderlichen Zugriff, um den Test durchzuführen.
Fabrikbeispiel:
Bei einer so geschriebenen Foo-Klasse:
In Ihrer Testmethode können Sie eine BarFactory wie folgt injizieren:
Bonus: Dies ist ein Beispiel dafür, wie TDD das Design Ihres Codes steuern kann.
quelle
Bar bar = mock(Bar.class)
anstelle vonBar bar = new Bar();
BarFactory myFactory = mock(BarFactory.class); when(myFactory.createBar()).thenReturn(bar);
Die klassische Antwort lautet: "Das tust du nicht." Sie testen die öffentliche API von
Foo
, nicht deren Interna.Gibt es ein Verhalten des
Foo
Objekts (oder, weniger gut, eines anderen Objekts in der Umgebung), das davon betroffen istfoo()
? Wenn ja, testen Sie das. Und wenn nicht, was macht die Methode?quelle
Foo
istpublic void foo()
, wo die Interna nur barbezogen sind.verify()
werde in der Tat sehr hilfreich, auch wenn du nicht mehr am heiligen Altar der Integrationstests verehrst.Wenn Sie DI oder Fabriken nicht verwenden möchten. Sie können Ihre Klasse auf etwas knifflige Weise umgestalten:
Und deine Testklasse:
Dann macht die Klasse, die Ihre foo-Methode aufruft, Folgendes:
Wie Sie sehen können, wenn Sie die Methode auf diese Weise aufrufen, müssen Sie die Bar-Klasse nicht in eine andere Klasse importieren, die Ihre foo-Methode aufruft, was möglicherweise etwas ist, das Sie möchten.
Der Nachteil ist natürlich, dass Sie dem Anrufer erlauben, das Balkenobjekt festzulegen.
Ich hoffe es hilft.
quelle
Lösung für Ihren Beispielcode mit
PowerMockito.whenNew
FooTest.java
JUnit-Ausgabe
quelle
Ich denke Mockito
@InjectMocks
ist der Weg.Abhängig von Ihrer Absicht können Sie Folgendes verwenden:
Weitere Infos in den Dokumenten
Unten ist ein Beispiel mit Feldinjektion:
Klassen:
Prüfung:
quelle
Ja, wenn Sie es wirklich wollen / müssen, können Sie PowerMock verwenden. Dies sollte als letzter Ausweg betrachtet werden. Mit PowerMock können Sie veranlassen, dass ein Aufruf vom Aufruf an den Konstruktor zurückgegeben wird. Führen Sie dann die Überprüfung auf dem Mock durch. Das heißt, csturtz ist die "richtige" Antwort.
Hier ist der Link zur Scheinkonstruktion neuer Objekte
quelle
Eine andere einfache Möglichkeit wäre, der bar.someMethod () eine Protokollanweisung hinzuzufügen und dann sicherzustellen, dass Sie die besagte Nachricht sehen können, wenn Ihr Test ausgeführt wird. Siehe Beispiele hier: So führen Sie eine JUnit-Bestätigung für eine Nachricht in einem Logger durch
Das ist besonders praktisch, wenn Ihre Bar.someMethod () ist
private
.quelle