MockitoまたはPowerMockを使用して、サブクラスによって実現されるが抽象スーパークラスから継承される保護されたメソッドをモックする方法は?
つまり、「doSomethingElse」をモックしながら「doSomething」メソッドをテストしたいのです。
抽象スーパークラス
public abstract class TypeA {
public void doSomething() {
// Calls for subclass behavior
doSomethingElse();
}
protected abstract String doSomethingElse();
}
サブクラスの実装
public class TypeB extends TypeA {
@Override
protected String doSomethingElse() {
return "this method needs to be mocked";
}
}
ソリューション
ここに記載されている回答は正しく、関連するクラスが同じパッケージに含まれている場合に機能します。
しかし、異なるパッケージが関係している場合、1つのオプションはPowerMockを使用することです。次の例は私のために働いた。もちろん、それを行う他の方法があるかもしれません、これはうまくいくものです。
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ TypeB.class })
public class TestAbstract {
@Test
public void test_UsingPowerMock() throws Exception {
// Spy a subclass using PowerMock
TypeB b = PowerMockito.spy(new TypeB());
String expected = "some value for mock";
// Mock a method by its name using PowerMock again
PowerMockito.doReturn(expected).when(b, "doSomethingElse");
// Calls the
String actual = b.doSomething();
assertEquals(expected, actual);
}
}
注:Java 5、jUnit 4.11、Mockito1.9.0およびPowerMock1.4.12。
抽象メソッドをモックするときにMockito.CALLS_REAL_METHODS
を使用できます。これにより、クラスの元のメソッドが呼び出され、すべての抽象メソッドを自分でモックできます。
TypeA typeA = mock(TypeA.class, Mockito.CALLS_REAL_METHODS);
when(typeA.doSomethingElse()).thenReturn("Hello");
typeA.doSomething();
または、スパイを使用してTypeBで直接テストします。
TypeB typeB = spy(new TypeB());
when(typeB.doSomethingElse()).thenReturn("Hello");
typeB.doSomething();
そのためにMockitoを使用することをお勧めします。
// Create a new Mock
final TypeA a = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS);
// Call the method
a.doSomething();
// Now verify that our mocked class' method was called
Mockito.verify(a, Mockito.times(1)).doSomethingElse();
次の方法でmockitoを使用して抽象クラスをテストできます
TypeA typA = Mockito.mock(TypeA.class, Mockito.CALLS_REAL_METHODS);
when(typA.doSomethingElse()).thenReturn("doSomethingElse");
Assert.assertSomething(typeA.doSomething());
抽象クラスでvoidを返すメソッドをモックするには、次のように使用できます。
MyAbstractClass abs = Mockito.mock(MyAbstractClass.class);
Mockito.doNothing().when(abs).myMethod(arg1,arg2....));
要件に応じて、引数をMockito.anyString()などに置き換えることができます。