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ück Hello!
  • 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 😀

InformationsquelleAutor Zarathustra | 2013-12-27
Schreibe einen Kommentar