15

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
    }
}

Here is the test case:

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

Console trace:

In privateAPI
In thirdPartyCall
In publicApi
result : 20
Masoud Mokhtari
  • 2,390
  • 1
  • 17
  • 45
Pankaj
  • 3,512
  • 16
  • 49
  • 83

1 Answers1

28

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

Example Partial Mocking of Private Method

Test code

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

Console trace

In publicApi
result : 20
clD
  • 2,523
  • 2
  • 22
  • 38
  • Hi thank you for your answer can you please take a look at my question which is related to this: http://stackoverflow.com/questions/35561709/can-not-mock-the-private-method-with-mockito – HMdeveloper Feb 22 '16 at 19:11
  • 4
    how about void private methods ? – Prasobh.Kollattu Mar 03 '17 at 09:00
  • can you please give some code for void with private methods using powerMockito? @cID – anand krish Nov 06 '17 at 07:57
  • @anandkrish - Could you please help me to resolve https://stackoverflow.com/questions/52052648/org-powermock-reflect-exceptions-methodnotfoundexception-no-method-found-with-n ? – Jeff Cook Aug 28 '18 at 07:48
  • @clD - Why are we expecting to have RunTimeException here ? If we don't want to go ahead without exception, then what do we need to change? – Jeff Cook Aug 28 '18 at 07:50
  • @cID - I tried the suggestions, but it's not working - https://stackoverflow.com/questions/57248656/how-to-mock-private-methods-using-powermockito?noredirect=1#comment100997810_57248656 – Vikash Yadav Jul 29 '19 at 07:42