Search code examples
javaunit-testingmockingmockitopowermockito

How to test void method with private method calls using Mockito


I have the following piece of code

public class A extends B {
private boolean workDone = false;
@Override
public void publicMethod(boolean flag) {
  if (!workDone) {
    privateMethod();
    workDone = true;
  }
  super.publicMethod(flag);
 }
 private void privateMethod() {
  // some logic here
 }
}

I'm new to mocking. I have following doubts. I'm trying to test the public method.

  1. is it possible for me to assert the value of private variable workDone?
  2. is it possible to verify the method call in the super class?
  3. How can I mock the private method call in the method?

Solution

  • If you really want to verify it, you need to change your A class and extract the super call into a private method:

    public class A extends B {
    
        private boolean workDone = false;
    
        @Override
        public void publicMethod(final boolean flag) {
            if (!workDone) {
                privateMethod();
                workDone = true;
            }
            callParentPublicMethod(flag);
        }
    
        private void callParentPublicMethod(final boolean flag) {
            super.publicMethod(flag);
        }
    
        private void privateMethod() {
            System.out.println("A: privateMethodCalled");
        }
    }
    

    after this is done you can use PowerMock to verify private method invocations:

      import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({ A.class })
    public class ATest {
    
        @Test
        public void publicMethod_test_false() throws Exception {
    
            A spy = PowerMockito.spy(new A());
            spy.publicMethod(false);
            PowerMockito.verifyPrivate(spy).invoke("privateMethod");
            PowerMockito.verifyPrivate(spy).invoke("callParentPublicMethod", false);
        }
    
        @Test
        public void publicMethod_test_true() throws Exception {
    
            A spy = PowerMockito.spy(new A());
            spy.publicMethod(true);
            PowerMockito.verifyPrivate(spy).invoke("privateMethod");
            PowerMockito.verifyPrivate(spy).invoke("callParentPublicMethod", true);
        }
    }
    

    Hope this helps.