How to stub private methods of class under test by Mockito

This could be achieved by PowerMockito framework.

import org.junit.Before;
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(SomeClass.class)
public class SomeClassTest {

    private SomeClass someInstance;

    @Before
    public void setUp() throws Exception {

        someInstance = PowerMockito.spy(new SomeClass());
    }

    @Test
    public void sendRequest() throws Exception {

        String json = "JSON";
        String text = "Some text";
        int messageId = 1;

        PowerMockito.doReturn(true).when(someInstance, "isMethod");
        PowerMockito.doReturn(messageId).when(someInstance, "getMessageId", json);

        someInstance.sendRequest(json, text);

        PowerMockito.verifyPrivate(someInstance).invoke("isMethod");
        PowerMockito.verifyPrivate(someInstance).invoke("getMessageId", json);
        PowerMockito.verifyPrivate(someInstance).invoke("sendMessage", messageId, text);
    }

}

In addition to what was said in this answer, I would add that the desire to test whether private method was called indicates that you are testing implementation as oppose to the public contract of a class. It is not an optimal idea, because it makes your refactoring more difficult. The idea of refactoring is that you can change inner workings of your code without violating it's contract. And your unit tests help you make sure that while changing the implementation, you did not introduce any changes to the contract.

So, in your case a better option would be to restructure your code so that your test calls public methods and verifies the result based on return values

Tags:

Java

Mockito