Counting indirect calls to the Mockito method

I'm having trouble calling the counting method using Mockito. The problem is that the whos calls method that I want to count is called in the test class indirectly by another method. Here is the code:

public class ClassForTest { private Integer value; public void doSmth() { prepareValue("First call"); prepareValue("Second call"); prepareValue("Third call"); System.out.println(value); } protected void prepareValue(String msg) { System.out.println("This is message: " + msg); value++; } } 

And the test class:

 public class ClassForTestTest extends TestCase { @Test public void testDoSmth() { ClassForTest testMock = mock(ClassForTest.class); doNothing().when(testMock).prepareValue(anyString()); testMock.doSmth(); verify(testMock, times(3)).prepareValue(anyString()); } } 

Having such an exception:

 Wanted but not invoked: classForTest.prepareValue(<any>); -> at org.testing.ClassForTestTest.testDoSmth(ClassForTestTest.java:24) However, there were other interactions with this mock: -> at org.testing.ClassForTestTest.testDoSmth(ClassForTestTest.java:21) 

Any ideas please. Thanks in advance!

+7
source share
4 answers

That will work. Using spy calls the base method. Make sure value initialized first.

  @Test public void testDoSmth() { ClassForTest testMock = spy(new ClassForTest()); testMock.doSmth(); verify(testMock, times(3)).prepareValue(anyString()); } public class ClassForTest { private Integer value = 0; public void doSmth() { prepareValue("First call"); prepareValue("Second call"); prepareValue("Third call"); System.out.println(value); } protected void prepareValue(String msg) { System.out.println("This is message: " + msg); value++; } } 
+10
source

This is an indication that you need refactoring to improve your design. One class should be fully tested without the need to mock it. Regardless of which parts that you consider necessary for bullying should be removed to one or more collaborating sites. Do not fall into the trap of partial layouts. Listen to what the tests tell you. Your future will be grateful to you.

+5
source

You are mocking the tested class. Mocking is for dependencies of the tested class, not the class itself.

I suspect you want Mockito.spy() . However, this is a partial mockery that Mockito Javadoc recommends.

+1
source

Alternatively, if you want to reorganize for verification, you can do the following:

 @Test public void testDoSmth() { Preparer preparer = mock(Preparer.class); ClassForTest cft = new ClassForTest(preparer); cft.doSmth(); verify(preparer, times(3)).prepareValue(anyString()); } public class ClassForTest { private final Preparer preparer; public ClassForTest(Preparer preparer) { this.preparer = preparer; } public void doSmth() { preparer.prepareValue("First call"); preparer.prepareValue("Second call"); preparer.prepareValue("Third call"); System.out.println(preparer.getValue()); } } public class Preparer { private Integer value = 0; public void prepareValue(String msg) { System.out.println("This is message: " + msg); value++; } public Integer getValue() { return value; } } 
+1
source

All Articles