使用PowerMockito模拟私有方法

问题描述:

我正在使用PowerMockito模拟私有方法调用(privateApi)但它仍然进行privateApi调用,而后者又调用另一个thirdPartCall。当thirdPartyCall抛出异常时,我遇到了问题。据我所知,如果我在模拟privateApi,它不应该进入方法实现细节并返回模拟响应。

I'm using PowerMockito to mock the private method call (privateApi) but it still makes the privateApi call which in turn makes another thirdPartCall. I'm getting into problem when thirdPartyCall throws exception. As far as I understand, if I'm mocking the privateApi, it shouldn't get into method implementation detail and return the mock response.

public class MyClient {

    public void publicApi() {
        System.out.println("In publicApi");
        int result = 0;
        try {
            result = privateApi("hello", 1);
        } catch (Exception e) {
            Assert.fail();
        }
        System.out.println("result : "+result);
        if (result == 20) {
            throw new RuntimeException("boom");
        }
    }

    private int privateApi(String whatever, int num) throws Exception {
        System.out.println("In privateAPI");
        thirdPartyCall();
        int resp = 10;
        return resp;
    }

    private void thirdPartyCall() throws Exception{
        System.out.println("In thirdPartyCall");
        //Actual WS call which may be down while running the test cases
    }
}

以下是测试用例:

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClient.class)
public class MyclientTest {

    @Test(expected = RuntimeException.class)
    public void testPublicAPI() throws Exception {
        MyClient classUnderTest = PowerMockito.spy(new MyClient());
        PowerMockito.when(classUnderTest, "privateApi", anyString(), anyInt()).thenReturn(20);
        classUnderTest.publicApi();
    }
}

控制台跟踪:

In privateAPI
In thirdPartyCall
In publicApi
result : 20


您只需要将模拟方法调用更改为使用 doReturn

You just need to change the mock method call to use doReturn.

私人方法的部分模拟示例

测试代码

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClient.class)
public class MyClientTest {

    @Test(expected = RuntimeException.class)
    public void testPublicAPI() throws Exception {
        MyClient classUnderTest = PowerMockito.spy(new MyClient());

        // Change to this  

        PowerMockito.doReturn(20).when(classUnderTest, "privateApi", anyString(), anyInt());

        classUnderTest.publicApi();
    }
}

控制台跟踪

In publicApi
result : 20