Gibt es eine Möglichkeit in JMockit die ursprüngliche Methode von einer verspottet Methode zu nennen?
Frage
In meiner mock Klasse, ich spöttisch Methode foo (). Für einige Testfälle, möchte ich die Mock-Implementierung von foo () einen besonderen Wert zurückzukehren. Für andere Testfälle, möchte ich die reale Umsetzung der foo () verwenden. Ich habe ein boolean in meiner mock Klasse definiert, so dass ich in der Mock-Methode bestimmen kann, ob ich den besonderen Wert zurückkehren möge, oder die „echte“ Methode verwenden. Das Problem ist, ich kann nicht scheinen, um herauszufinden, wie die reale Methode aus der verspottet Methode aufrufen.
Ich fand, dass Sie ein spezielles Element innerhalb des Mock-Objekts definieren können den Namen „es“ (mit Art des Objekts verspottet). Auf diese Weise können Sie die echte Klasse von der Mock Umsetzung verweisen. Also, mein Plan war, wenn ich brauchte die „echte“ Implementierung von foo () aufrufen, würde die Mock-Methode aufrufen it.foo (). Allerdings bedeutet dies nicht, weil Aufruf it.foo () nur die Mock-Version ruft wieder, nicht die reale Version, so dass ich am Ende mit unendlicher Rekursion.
Gibt es eine Möglichkeit, diese Arbeit zu machen?
EDIT: es könnte mit einem Codebeispiel klarer sein, hier ist was meine aktuelle verspottet Methode Umsetzung wie folgt 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: Auch für die meisten meiner Testfälle ich tun nicht die Mock-Implementierung soll. Also mein erster Versuch war nur Mockit.redefineMethods () aufrufen, die in diesen Testfällen, wo ich das Mock-Objekt benötigt. Aber das hat nicht funktioniert -. Es scheint, können Sie dies nur tun, im Setup / Teardown ... meine Mock Implementierung nie genannt wurde, als ich das versucht,
HINWEISE ZUR LÖSUNG:
Zuerst dachte ich nicht, die Antwort gegeben gearbeitet, aber mit ihm etwas mehr nach dem Spiel, so scheint es, das Problem ist, dass ich JMockit „Kern“ Methoden der „Anmerkung“ angetrieben Methoden gemischt. Offenbar, wenn die Anmerkung verwenden, müssen Sie Mockit.setupMocks verwenden, nicht Mockit.redefineMethods (). Dies ist, was schließlich arbeitet:
@Before
public void setUp() throws Exception
{
Mockit.setUpMocks(MyMockClass.class);
}
Dann wird für die Mock-Klasse:
@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();
}
}
}
Lösung
Ich glaube, Sie können dies tun, mit der @Mock
Anmerkung. Aus den Dokumenten, @Mock(reentrant=true)
auf Ihrer Mock Klasse sollte es tun.
Siehe http://jmockit.googlecode.com/ svn / trunk / www / javadoc / mockit / Mock.html
Ein Beispiel hier http: // JMockit. googlecode.com/svn/trunk/www/tutorial/StateBasedTesting.html#reentrant
ich dies allerdings nicht getestet ..
Andere Tipps
In den neueren Versionen von JMockit, Invocation.proceed()
kann aus einer MockUp
Implementierung aufgerufen werden. Siehe Faking. Ausgehend in die reale Umsetzung
public class MyMockClass extends MockUp<RealClass> {
private static boolean fakeIt = false;
@Mock
public SomeClass foo(Invocation inv) {
if (fakeIt) {
return new SomeClass("fakevalue");
} else {
return inv.proceed();
}
}
}
Statt in einem Mock-Objekt werfen Sie auch die Objektunterklasse können Sie die Methoden testen und außer Kraft setzen möchten, die spezielle Werte zurückgeben soll.
Zum Beispiel:
RealClass toTest = new RealClass(){
public String foo(){
return "special value";
}
}
//use toTest in test
Diese Definition in Ihrem Test, indem sie es ist auch klar, für andere, die Methoden ‚verspottet‘ werden.