Jmockit Expectations/Verifications for calls to private methods when testing a public method

jmockit

Can anyone advise if it is possible to use an expectations/verifications to test that private methods are being called the-right-number-of-times/right-parameters.

The Class under test has been Mocked-Up – with one private method overridden.

Am Testing a public method which calls into a number of private methods.

I wish to know if it is possible to verify the calls to other private methods which will be called when the public method is being executed ?

Some idea of the code/class under test;

public class UnderTest {

    public void methodPublic(arg 1){
        .....
        methodPrivate1(var1);
        ....
        methodPrivate2(var2);
    }

    private void methodPrivate1(var1){
        //do stuff
    }

    private void methodPrivate2(var1){
        //do stuff
    }

}

In my test case

@Test
public void stateBasedTestMethod()
{
    UnderTest underTest;

    new MockUp<UnderTest>() {
        @Mock(invocations = 1)
        private void methodPrivate2(var1) {
            //do nothing in the mocked case
        }
    };

    underTest = new UnderTest();
    underTest.methodPublic(arg1);

    new Verifications() {{
        // Is there a way to test that methodPrivate1 has been called-once/with-expected-arguments
    }};
}

Edited in response to the answer from Rogério.
I am using jmockit 1.12
and the Verifications is FAILING as the method using the provided solution is invoking the method twice as I thought from the JMockit documentation.

Failure Trace;
mockit.internal.UnexpectedInvocation: Expected exactly 1 invocation(s) of MyHelperTest$1#method3…, but was invoked 2 time(s)

Included is the full code I am using for this.
As described above – my goal is to mock one of the private methods to do nothing.
And ensure that I can verify that the other private method is called only once.

Thanks in advance and hopefully will get a better understanding if this is possible with Jmockit.

Test Code.

public class MyHelperTest {

    @Test
    public void testHelper(@Mocked final MyDependent myDependent) {

        final MyHelper myHelper;

        new MockUp<MyHelper>() {

            @Mock(invocations = 1)
            private void method3(MyDependent myTable) {
                System.out.println("In Mocked Method");
                //do nothing in the mocked case
            }

        };

        myHelper = new MyHelper();

        myHelper.method1(myDependent);

        new Verifications() {{ 
            invoke(myHelper, "method2", myDependent); times = 1; 
        }};
    }

}

Class under test.

public class MyHelper {

    public void method1(MyDependent myDependent){
        method2(myDependent);
    }

    private void method2(MyDependent myDependent) {
        myDependent.setValue(1);
        method3(myDependent);
    }

    private void method3(MyDependent myDependent) {
        myDependent.setValue(2);
    }

}

Dependent Class

public class MyDependent {

    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

}

Best Answer

It's possible, though not recommended to mock private methods.

Using the Expectations API:

@Tested @Mocked MyHelper myHelper;

@Test
public void testHelper(@Mocked final MyDependent myDependent)
{
    new NonStrictExpectations() {{ invoke(myHelper, "method3", myDependent); }};

    myHelper.method1(myDependent);

    new Verifications() {{ invoke(myHelper, "method2", myDependent); times = 1; }};
}

... where the invoke(...) method is statically imported from class mockit.Deencapsulation.

Related Topic