Search code examples
javaandroidunit-testingmockitopowermockito

Mocking private method with PowerMock


I'm trying to test the next method:

public void methodToTest() {
    // Other stuff
    privateMethod(false).execute(new Void[0]);
}

Which is calling the privateMethod:

private AsyncTask<Void, Void, CustomObject> privateMethod(final boolean renew) {
    AsyncTask<Void, Void, CustomObject> asyncTask = new AsyncTask<Void, Void, CustomObject>() {

        @Override
        protected CustomObject doInBackground(Void... params) {
            CustomObject custom = new CustomObject();

            return custom;
        }
        protected void onPostExecute(CustomObject custom) {
            //some code
        }
    };

The execute of the asyncTask cannot be done in a test with Mockito so I need to mock it somehow. I've tried mocking the private method with PowerMock:

@Mock Context mockContext;
@Mock AsyncTask<Void, Void, CustomObject> mockAsyncTask;

@Test
public void methodTest() {
    ClassToTest objectToTest = new ClassToTest(mockContext);
    try {
        PowerMockito.doReturn(mockAsyncTask).when(objectToTest, "privateMethod", ArgumentMatchers.anyBoolean());
    objectToTest.methodToTest();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

This is giving me an exception in the PowerMockito line (NullPointerException) saying

Method threw 'org.mockito.exceptions.misusing.UnfinishedStubbingException' exception. Cannot evaluate android.os.AsyncTask$MockitoMock$1952591544.toString()

Now I'm running out of ideas on how to mock this object.


Solution

  • I finally found the answer:

    @Test
    public void methodTest() {
        ClassToTest objectToTest = PowerMockito.spy(new ClassToTest());
        try {
            when(objectToTest, method(ClassToTest.class, "privateMethod", boolean.class)).withArguments(false).thenReturn(mockAsyncTask);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    And also just before the class declaration:

    @PrepareForTest(ClassToTest.class)