Ich habe eine private Methode in meiner Testklasse, die ein häufig verwendetes Bar
Objekt erstellt. Der Bar
Konstruktor ruft die someMethod()
Methode in meinem verspotteten Objekt auf:
private @Mock Foo mockedObject; // My mocked object
...
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
}
In einigen meiner Testmethoden, die ich überprüfen möchte, someMethod
wurde auch von diesem bestimmten Test aufgerufen. So etwas wie das folgende:
@Test
public void someTest() {
Bar bar = getBar();
// do some things
verify(mockedObject).someMethod(); // <--- will fail
}
Dies schlägt fehl, da das verspottete Objekt someMethod
zweimal aufgerufen wurde. Ich möchte nicht, dass sich meine Testmethoden um die Nebenwirkungen meiner getBar()
Methode kümmern. Wäre es also sinnvoll, mein Scheinobjekt am Ende von zurückzusetzen getBar()
?
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
reset(mockedObject); // <-- is this OK?
}
Ich frage, weil die Dokumentation vorschlägt , dass das Zurücksetzen von Scheinobjekten im Allgemeinen auf schlechte Tests hindeutet. Dies fühlt sich für mich jedoch in Ordnung an.
Alternative
Die alternative Wahl scheint zu sein:
verify(mockedObject, times(2)).someMethod();
was meiner meinung nach jeden test zwingt, über die erwartungen von zu wissen getBar()
, ohne gewinn.
Mockito.clearInvocations(T... mocks)
Extrahiert aus den Mockito-Dokumenten .
Mein Rat ist, dass Sie versuchen, die Verwendung zu vermeiden
reset()
. Meiner Meinung nach sollte ein zweimaliger Aufruf von someMethod getestet werden (möglicherweise handelt es sich um einen Datenbankzugriff oder einen anderen langen Prozess, um den Sie sich kümmern möchten).Wenn Ihnen das wirklich egal ist, können Sie Folgendes verwenden:
Beachten Sie, dass dies zu einem falschen Ergebnis führen kann, wenn Sie someMethod von getBar und nicht danach aufrufen (dies ist ein falsches Verhalten, aber der Test schlägt nicht fehl).
quelle
verify
meine private Methode nicht aufrufe (was meiner Meinung nach wahrscheinlich nicht dazugehört). Ich begrüße Ihre Kommentare dazu, ob sich Ihre Antwort ändern würde.Absolut nicht. Wie so oft ist die Schwierigkeit, einen sauberen Test zu schreiben, eine große rote Fahne für das Design Ihres Produktionscodes. In diesem Fall ist die beste Lösung, den Code so umzugestalten, dass der Konstruktor von Bar keine Methoden aufruft.
Konstruktoren sollten konstruieren, keine Logik ausführen. Nehmen Sie den Rückgabewert der Methode und übergeben Sie ihn als Konstruktorparameter.
wird:
Wenn dies dazu führen würde, dass diese Logik an vielen Stellen dupliziert wird, sollten Sie eine Factory-Methode erstellen, die unabhängig von Ihrem Bar-Objekt getestet werden kann:
Wenn dieses Refactoring zu schwierig ist, ist die Verwendung von reset () eine gute Lösung. Aber lassen Sie uns klar sein - es zeigt an, dass Ihr Code schlecht gestaltet ist.
quelle