bharanitharan
bharanitharan

Reputation: 2629

PowerMock not verifying private calls more than once

Class to be tested
    public class ClassUnderTest {
    public void functionA() {
        functionB();
        functionC();
    }
    private void functionB() {
    }
    private void functionC() {
    }
}

Test Class

@RunWith(PowerMockRunner.class)
public class TestClass {
        @Test
        public void testFunctionA() throws Exception {
            ClassUnderTest classUnderTest = PowerMockito.spy(new ClassUnderTest());
            classUnderTest.functionA();
            PowerMockito.verifyPrivate(classUnderTest).invoke("functionB");
            PowerMockito.verifyPrivate(classUnderTest).invoke("functionC");
        }
    }

While executing the test class I'm getting the following error,

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here:
-> at org.powermock.api.mockito.PowerMockito.verifyPrivate(PowerMockito.java:312)

Example of correct verification:
    verify(mock).doSomething()

Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.

If one verification is commented then the test case works fine.

Upvotes: 2

Views: 2326

Answers (3)

王山栋
王山栋

Reputation: 1

You can try adding two lines of code

@RunWith(PowerMockRunner.class)
public class TestClass {
        @Test
        public void testFunctionA() throws Exception {
            ClassUnderTest classUnderTest = PowerMockito.spy(new ClassUnderTest());
            PowerMockito.doNothing().when(classUnderTest, "functionB");
            PowerMockito.doNothing().when(classUnderTest, "functionC");
            classUnderTest.functionA();
            PowerMockito.verifyPrivate(classUnderTest).invoke("functionB");
            PowerMockito.verifyPrivate(classUnderTest).invoke("functionC");
        }
    }

Upvotes: 0

GhostCat
GhostCat

Reputation: 140523

Another idea: don't do that. Do not verify private methods. Those methods are private for a reason. You should really try to avoid to write tests that have to know that some private method was called.

You see, the idea of private is: it is subject to change. A good unit test works with observing the behavior of your class - you call public methods with different arguments; and you check the results coming back. Or maybe, you use dependency injection to provide mocked objects to your test class - when your test code needs those other methods to do its job.

But you should really not start checking private methods. The point is: those private methods should do something that is observable from the outside. Either they work on the final "return" value; or they change some internal state that might be checked in other ways. In other words: if those private methods do not cause any other effect on your class under test - what would be their purpose anyway?!

Upvotes: -1

kswaughs
kswaughs

Reputation: 3087

You have to add ClassUnderTest in PrepareForTest.

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassUnderTest.class)
public class TestClass {

@Test
public void testFunctionA() throws Exception {
    ClassUnderTest classUnderTest = PowerMockito.spy(new ClassUnderTest());
    classUnderTest.functionA();

   PowerMockito.verifyPrivate(classUnderTest).invoke("functionB");
   PowerMockito.verifyPrivate(classUnderTest).invoke("functionC");
 }

I have just added sysouts in private methods & run the test class.

Upvotes: 3

Related Questions