Mock alle Instanzen einer Klasse
Ich weiß, das ist in der Regel eine schlechte Praxis, aber in meinem Fall ist es notwendig.
Habe ich einen Fall, wo ein Enum enthält eine Klasse um zu gewinnen einige Informationen. So, dass Enum erstellt eine Instanz dieses calss in seinem Konstruktor.
public enum MyEnum {
CONSTANT(new MyImpl());
private final MyImpl myImpl;
private MyEnum(final MyImpl impl) {
this.myImpl = impl;
}
public void sayHello() {
System.out.println(this.myImpl.getSomethingToSay());
}
}
MyImpl.java
nur eine Klasse mit einer einzigen Methode, die einen String zurückgibt.
public class MyImpl {
public String getSomethingToSay() {
return "Hello!";
}
}
Nun endlich das Gerät testen:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
@RunWith(MockitoJUnitRunner.class)
@PrepareForTest({ MyImpl.class, MyEnum.class })
public class MyEnumTest extends PowerMockTestCase {
@Test
public void testSmth2() throws Exception {
MyImpl impl = Mockito.mock(MyImpl.class);
Mockito.when(impl.getSomethingToSay()).thenReturn("It works!");
PowerMockito.whenNew(MyImpl.class).withAnyArguments().thenReturn(impl);
System.out.println(impl.getSomethingToSay());
System.out.println(new MyImpl().getSomethingToSay());
MyEnum.CONSTANT.sayHello();
}
}
Ausgabe:
It works!
Hello!
Hello!
Aber sollte 3 mal funktioniert es!
- Auch wenn man
whenNew
verwendet werden, so oft wie Sie wollen, es werden nur noch helfen, wenn Sie können angeben, dass vor der enum initialisiert wird - und wenn Sie das tun können, werde es sein, so verwendet für alle tests, bis Sie einen neuen classloader. Ich würde wirklich versuchen zu einer Neugestaltung dieser spöttischen eine Abhängigkeit von einem enum ist wirklich, wirklich böse. - Aber wenn ich den mocking-block in einem static-block,
System.out.println(new MyImpl().getSomethingToSay());
würde noch zurückHello!
- Ich bin mir nicht ganz sicher, wie das relevant ist...
- Ich missverstanden, dein Erster Kommentar. Okay was ist dann mit den lustig das Enum selbst?
- Nein, ich würde nicht tun, dass entweder. Ich würde ändern Sie Ihre design, so dass Sie nicht haben eine enum, die eine komplexe Abhängigkeit (als Membervariable) wie diese. Sie könnte in Betracht ziehen, die Abhängigkeit als parameter an Methoden innerhalb der Enumeration, zum Beispiel.
- Tut PowerMock lassen Sie mock Enums? Selbst wenn es funktioniert, ich glaube nicht, dass es eine gute Idee.
- natürlich keine so gute Idee 😀
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fand ich das defekte Teil.
Änderte ich
zu
Nun der Spott funktioniert. Aber ich muss sagen, dass wie Jon Skeet ausgedruckt, die enum nicht überall verspottet Mitglied-Instanz. Also in einem anderen Unit-test aufrufen
MyEnum.CONSTANT.sayHello();
wird drucken wiederit works
stattHello!
.