In meiner Mock-Klasse spotte ich der Methode foo(). Für einige Testfälle möchte ich, dass die Mock-Implementierung von foo() einen speziellen Wert zurückgibt. Für andere Testfälle möchte ich die echte Implementierung von foo() verwenden. Ich habe in meiner Mock-Klasse einen Booleschen Wert definiert, so dass ich in der Mock-Methode festlegen kann, ob ich den speziellen Wert zurückgeben oder die "echte" Methode verwenden möchte. Das Problem ist, dass ich nicht herausfinden kann, wie ich die echte Methode von der nachgebildeten Methode aus aufrufen kann.
Ich habe herausgefunden, dass man innerhalb des Mock-Objekts ein spezielles Mitglied mit dem Namen "it" (mit dem Typ des zu spiegelnden Objekts) definieren kann. Dies ermöglicht es Ihnen, die echte Klasse von der Mock-Implementierung zu referenzieren. Mein Plan war also, wenn ich die "echte" Implementierung von foo() aufrufen müsste, würde die Mock-Methode it.foo() aufrufen. Dies funktioniert jedoch nicht, weil der Aufruf von it.foo() nur die Mock-Version erneut aufruft, nicht die echte Version, so dass ich am Ende eine unendliche Rekursion habe.
Gibt es eine Möglichkeit, dies zu bewerkstelligen?
EDIT: es könnte klarer sein, mit einem Code-Beispiel, hier ist, was meine aktuelle Mocked-Methode-Implementierung wie aussieht:
private RealClass it;
...
public SomeClass foo() {
if(fakeIt) {
return new SomeClass("fakevalue");
} else {
// doesn't work, just keeps calling the mock foo
// in infinite recursion
return it.foo();
}
}
EDIT 2: Außerdem mache ich für die meisten meiner Testfälle PAS die Mock-Implementierung wünschen. Mein erster Versuch bestand also darin, Mockit.redefineMethods() nur in den Testfällen aufzurufen, in denen ich das Mock-Objekt benötigte. Aber das hat nicht funktioniert - es scheint, dass Sie dies nur innerhalb von setup/teardown tun können ... meine Mock-Implementierung wurde nie aufgerufen, wenn ich das versuchte.
HINWEISE ZUR LÖSUNG:
Zuerst dachte ich nicht, dass die gegebene Antwort funktionierte, aber nach dem Spielen mit ihm einige mehr, es scheint das Problem ist, dass ich JMockit "Kern" Methoden mit der "Annotation" angetrieben Methoden gemischt wurde. Offenbar müssen Sie bei Verwendung der Annotation Mockit.setupMocks verwenden, nicht Mockit.redefineMethods(). Dies ist, was schließlich funktionierte:
@Before
public void setUp() throws Exception
{
Mockit.setUpMocks(MyMockClass.class);
}
Dann, für den Probeunterricht:
@MockClass(realClass = RealClass.class)
public static class MyMockClass {
private static boolean fakeIt = false;
private RealClass it;
@Mock(reentrant = true)
public SomeClass foo() {
if(fakeIt) {
return new SomeClass("fakevalue");
} else {
return it.foo();
}
}
}