#はじめに
MockitoとPowermockを利用したJUnitにおいて、どうしてもsuper
を利用した親クラスの処理をモックする必要があって結構悩んだので、メモしておきます。調べるとPowerMockito.suppress()
を使えってのは結構出てくるのですが、suppress()
だとスキップ処理されるだけであり、きちんとこちらの想定するモックオブジェクトを返してくれいとうまくJUnitの後続処理を実行できない状態でした。
#テスト対象クラス
サンプルのコードを以下に記載します。DTOクラスは省略します。
親クラス
public class Parent {
public OutputDto execute (InputDto input) {
System.out.println("Parent#execute()");
OutputDto out = new OutputDto();
out.setText(input.getText());
return out;
}
}
子クラス
public class Child extends Parent {
public OutputDto execute (InputDto input) {
System.out.println("Child#execute()");
OutputDto out = super.execute(input);
out.setText(out.getText()+" updated in Child.");
return out;
}
}
子クラスで、super.execute()
をして戻り値を期待しているところがポイントです。
JUnitテストクラス
@RunWith(PowerMockRunner.class)
@PrepareForTest({Parent.class})//親を指定
public class MockSuperTest {
// テスト対象クラス
@InjectMocks
private Child child;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void testExecute1() {
//入力データ準備
InputDto input = new InputDto();
input.setText("hello");
OutputDto result = new OutputDto();
result.setText("hello updated in Child.");
try {
Method method = child.getClass().getMethod("execute", InputDto.class);
PowerMockito.replace(method).with(
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("replaced execute()!!");
return result;
}
});
} catch (Exception e) {
e.printStackTrace();
fail();
}
OutputDto testOut = child.execute(input);
assertEquals(result.getText(), testOut.getText());
}
}
#実行結果
上記のJUnitを実行すると、
Child#execute()
replaced execute()!!
となり、子クラスのexecute()
を呼んだ後、super.execute()
のところがPowerMockito.replace()
で指定した内容に置き換わっています。
ちなみに、
@PrepareForTest({Child.class})//子を指定
public class MockSuperTest {
のところを子クラスの方で指定すると、結果は
replaced execute()!!
となり子クラスのexecute()
を直接変更します。普通に実行するともちろん
Child#execute()
Parent#execute()
が期待値です。
以上です。