Mockito mocking a method calls the actual method

Viewed 22524

I am trying to mock method createInstanceB() using Mockito.when() as well as doReturn(). This always calls real method.

For example:

Class A {
  public B createInstanceB(any, any) {
    B b = new B();
    b.api();
  }
}

I am using the code below

import org.mockito.Mockito;
import static org.mockito.Mockito.*;

    Class ATest {
      A a;
      B b;

      @Before
      Public void setup{
        a = A.getInstance();
        b = mock(B.class);
      }
  
      @Test
      public void testCreateInstanceB(){
        Mockito.when(a.createInstanceB(any(),any()).thenReturn(b);
        ...
      }
    }

I tried doReturn(mock) as well.

4 Answers

As StvnBrkdll recommended, use a Spy if you're needing to use an actual instance. But that can still call the real method sometimes if using Mockito.when() as you are in your example. As an alternative, look at Mockito.doReturn(). For example using your code: Mockito.doReturn(b).when(a).createInstanceB(any(),any()); This will now only return b and never call the actual method of createInstanceB.

Btw, their docs have a section about this. See the part under "Important gotcha on spying real objects!"

I faced this problem. Both of these methods thenReturn() and doReturn() seem to do the same in my case: that is they are calling the actual method. Using stub worked for me:

PowerMockito.stub(PowerMockito.method(A.class, "createInstance", argtypes)).toReturn(b);

Make sure you mock the constructor of A as well as using PowerMockito.whenNew() if you create a new object and add A.class to @PrepareForTest.

As per @StvnBrkdll's answer, in my case the problem was that I was using the @Autowired annotation instead of @MockBean for the method I was trying to mock, and that was causing the real implementation to be called.

Related