web-dev-qa-db-ja.com

クラスのすべてのインスタンスをモックします

これは通常悪い習慣ですが、私の場合は必要です。

列挙型がいくつかの情報を取得するためのクラスを保持している場合があります。そのため、Enumはコンストラクターにそのcalsのインスタンスを作成します。

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は、文字列を返す単一のメソッドを持つ単なるクラスです。

public class MyImpl {

    public String getSomethingToSay() {
        return "Hello!";
    }

}

最後に、ユニットテスト:

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();
    }
}

出力は次のとおりです。

It works!
Hello!
Hello!

しかし、それは3倍になるはずです!

12
Zarathustra

不良品を見つけました。

私が変更され

_@RunWith(MockitoJUnitRunner.class)
_

_@RunWith(PowerMockRunner.class)
_

これで、モックが機能します。しかし、Jon Skeetが印刷したように、列挙型には、あざけられたメンバーインスタンスがどこにでもあるわけではありません。したがって、別の単体テストでは、MyEnum.CONSTANT.sayHello();を呼び出すと、_it works_ではなく_Hello!_が再度出力されます。

7
Zarathustra