LoginSignup
0
2

More than 3 years have passed since last update.

PowerMockでsuperメソッド呼び出しをモックする方法

Posted at

はじめに

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

が期待値です。

以上です。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2