user2572526
user2572526

Reputation: 1279

Use Powermockito to check if a private method is called or not

I would like to check if a private method of my class to test is executed or not using powermockito.

Suppose that I have this class to test:

public class ClassToTest {
    public boolean methodToTest() {
        //doSomething (maybe call privateMethod or maybeNot)
        return true;
    }

    //I want to know if this is called or not during the test of "methodToTest".
    private void privateMethod() {
        //do something
    }
}

When I test "methodToTest" I want to check if it returns the correct result but also if it executes the private method "privateMethod" or not. Searching on other discussion I wrote this test that makes use of powermockito but it doesnt works.

public class TestClass {

    @Test
    testMethodToTest(){
        ClassToTest instance = new ClassToTest();
        boolean result = instance.methodToTest();
        assertTrue(result, "The public method must return true");

        //Checks if the public method "methodToTest" called "privateMethod" during its execution.
        PowerMockito.verifyPrivate(instance, times(1)).invoke("privateMethod");
    }
}

When I use the debugger it seems that the last line (PowerMockito.verifyPrivate...) doesn't check if the private method has been executed once during the test but instead it seems that it executes the private method itself. Furthermore the test passes but using the debugger I'm sure that the private method is not executed during the call of "instance.methodToTest()". What is wrong?

Upvotes: 1

Views: 2110

Answers (1)

Jakub Bibro
Jakub Bibro

Reputation: 1640

I'd do it easier way, without PowerMockito. Consider this (it's some kind of Spy object):

public class TestClassToTest {

    private boolean called = false;

    @Test
    public void testIfPrivateMethodCalled() throws Exception {
        //given
        ClassToTest classToTest = new ClassToTest() {
            @Override
            void privateMethod() {
                called = true;
            }
        };

        //when
        classToTest.methodToTest();

        //then
        assertTrue(called);
    }
}

This requires changing privateMethod() to package-private (but there's nothing wrong with this).

But bear in mind, that testing implementation is a bad practise and can lead to fragile tests. Instead you should test only results.

Upvotes: 1

Related Questions