Mocking ein Spion Methode mit Mockito
Schreibe ich einen unit test für eine FizzConfigurator
Klasse, aussieht:
public class FizzConfigurator {
public void doFoo(String msg) {
doWidget(msg, Config.ALWAYS);
}
public void doBar(String msg) {
doWidget(msg, Config.NEVER);
}
public void doBuzz(String msg) {
doWidget(msg, Config.SOMETIMES);
}
public void doWidget(String msg, Config cfg) {
//Does a bunch of stuff and hits a database.
}
}
Ich würde gerne schreiben ein einfaches unit-test-stubs, die doWidget(String,Config)
Methode (so dass es nicht wirklich Feuer und hit-Datenbank), aber das erlaubt mir, mich überprüfen, dass der Aufruf doBuzz(String)
endet die Ausführung doWidget
. Mockito scheint, wie das richtige Werkzeug für den job hier.
public class FizzConfiguratorTest {
@Test
public void callingDoBuzzAlsoCallsDoWidget() {
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)).
thenThrow(new RuntimeException());
try {
fixture.doBuzz("This should throw.");
//We should never get here. Calling doBuzz should invoke our
//stubbed doWidget, which throws an exception.
Assert.fail();
} catch(RuntimeException rte) {
return; //Test passed.
}
}
}
Diese scheint wie ein guter gameplan (für mich zumindest). Aber wenn ich tatsächlich gehe es code, ich bekomme die folgende compiler-Fehlermeldung auf der 2. Linie im test-Methode (die Mockito.when(...)
Linie:
Dem Verfahren, wenn(T) in der Art Mockito ist nicht anwendbar für die Argumente (void)
Sehe ich, dass Mockito kann nicht verspotten eine Methode, die zurückgibt void
. Also Frage ich:
- Bin ich nähert sich diesem test-setup korrekt? Oder gibt es eine bessere, Mockito-empfehlenswert, Art der Prüfung, die
doBuzz
AnrufedoWidget
unter der Haube? Und - Was kann ich dagegen tun mocking/stubbing
doWidget
wie es die meisten kritischen Methode meiner gesamtenFizzConfigurator
Klasse?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich würde nicht mit Ausnahmen zu testen, aber Prüfungen. Und ein weiteres problem ist, dass Sie nicht verwenden können
when()
mit Methoden, die Rückgabe ungültig.Hier ist, wie ich es tun würde:
when()
können nicht verwendet werden, die auf Spione - werfen Sie einen Blick auf die Mockito-Dokumentation auf mit spies (beachten Sie den Punkt) und die do* - Methoden.Mockito.reset
eingeschlichen hat in Ihr code - den mock vergisst Interaktionen & Stubs.Dies ist ein klares Zeichen, dass
doWidget
Methode gehören sollte, auf eine andere Klasse, dieFizzConfigurator
davon abhängen würde.In Ihrem test, diese neue Abhängigkeit wäre eine Attrappe, und man kann leicht überprüfen, ob die Methode aufgerufen wurde, mit
verify
.In meinem Fall für die Methode, die ich versuchte, stub, ich lief in die falsche Matcher.
Meiner Signatur der Methode (für die super-Klasse Methode, die ich versuchte zu stub): String-Objekt.
Ich war vorbei, in:
myMethod("string", Mockito.nullable(ClassType.class))
und immer:Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
Wenn mit einem matcher in einem anderen parameter, die wir auch benötigen, um einen für die Zeichenfolge:
myMethod(eq("string"), Mockito.nullable(ClassType.class))
Hoffe, das hilft!