Mocking private methods used in public method with PowerMock, Mockito, and TestNG

java, mockito, powermock, testng

Solution

I don't think this is a problem with PowerMock. It looks like it should work just fine as is. I wonder if there is a problem with TestNG interacting with PowerMock?

I have no experience with TestNG, so I tried running the class in JUnit. `SomeClass` was left as is, `SomeClassTest` was minimally modified to use JUnit:

import static org.powermock.api.mockito.PowerMockito.*;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeClass.class)
public class SomeClassTest {

    @Test
    public void testSomePublicMethod() throws Exception {
        final int num = 4;

        final SomeClass someClassSpy = spy(new SomeClass());

        doReturn(8).when(someClassSpy, "somePrivateMethod1", num);
        doReturn(12).when(someClassSpy, "somePrivateMethod2", num);

        final int result = someClassSpy.somePublicMethod(num);

        Assert.assertEquals(result, 20);
    }
}

The test passes.

Do you need to specify a `PowerMockRunner.class` using `@RunWIth` or some similar annotation, as with JUnit? If I remove that annotation I recieve the same error message you posted.

EDIT:

According to this link: http://code.google.com/p/powermock/wiki/TestNG_usage

You need to tell TestNG to use the PowerMock object factory. To do this programmatically, add a method like this to your test class:

@ObjectFactory
public IObjectFactory getObjectFactory() {
    return new org.powermock.modules.testng.PowerMockObjectFactory();
}

or to be on the safe side you can also extend from the PowerMockTestCase:

@PrepareForTest(SomeClass.class)
public class SomeClassTest extends PowerMockTestCase {
   //...
}

Problem

I want to write a unit test for a class I have. This class has a public method, and inside the public method there are calls to private methods in the same class. I want to mock the calls to those private methods. The class is similar to this: ``` public class SomeClass { public int somePublicMethod(int num) { int num2 = somePrivateMethod1(num); int num3 = somePrivateMethod2(num); return num2 + num3; } private int somePrivateMethod1(int num) { return 2*num; } private int somePrivateMethod2(int num) { return 3*num; } } ``` For my unit test I am trying to use PowerMock with Mockito and TestNG. Here is my attempt at a test that tests somePublicMethod: ``` import static org.powermock.api.mockito.PowerMockito.doReturn; import static org.powermock.api.mockito.PowerMockito.spy; import org.powermock.core.classloader.annotations.PrepareForTest; import org.testng.Assert; import org.testng.annotations.Test; @PrepareForTest(SomeClass.class) public class SomeClassTest { @Test public void testSomePublicMethod() throws Exception { int num = 4; SomeClass someClassSpy = spy(new SomeClass()); doReturn(8).when(someClassSpy, "somePrivateMethod1", num); doReturn(12).when(someClassSpy, "somePrivateMethod2", num); int result = someClassSpy.somePublicMethod(num); Assert.assertEquals(result, 20); } } ``` When I run this test I get an exception and some hints: ``` FAILED: testSomePublicMethod org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here: -> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:31) E.g. thenReturn() may be missing. Examples of correct stubbing: when(mock.isOk()).thenReturn(true); when(mock.isOk()).thenThrow(exception); doThrow(exception).when(mock).someVoidMethod(); Hints: 1. missing thenReturn() 2. you are trying to stub a final method, you naughty developer! ``` I've looked at some examples online but I haven't found one that uses PowerMock with Mockito and TestNG specifically to do what I want. Can someone give me some pointers on what I could do differently?

Original source