3

I have an object whose method functionality I want to replace by just incrementing a counter when its called. The method has a void return type though, so I've been looking into how to stub void methods using mockito, but have not found a solution that works. From what I read I thought I could do something like this:

int count = 0;
Mockito.doReturn(++count).when(mockObject).mockObjectMethod(Mockito.anyString());

When I run this, I get

org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue

So I believe I found two solutions: use doThrow, where I could catch the exception and increment the counter OR use toAnswer and increment the counter in the implementation of the Answer. Are there other solutions?

WillardSolutions
  • 2,316
  • 4
  • 28
  • 38
user1491636
  • 2,355
  • 11
  • 44
  • 71

1 Answers1

2

doThrow is a really unconventional way to handle this, and I very much recommend against it—especially because it's an unusual code path, and one that will prevent the rest of your method-under-test from working after the thrown exception.

doAnswer is a much more appropriate way to make arbitrary behavior happen as the result of a void method, including counting.

However, if the purpose of the counter is to simply ensure that a method is called an exact number of times, then you don't want stubbing at all; Mockito's default for void methods is to do nothing except for recording the invocation, which is fine for this case. Instead, use verification:

verify(mockObject, times(EXPECTED_COUNT)).mockObjectMethod(anyString());

As a side note, be very careful not to confuse this:

doReturn(++count).when(mockObject).mockObjectMethod(Mockito.anyString());

with (hypothetical) syntax like this:

doReturn(() -> ++count).when(mockObject).mockObjectMethod(Mockito.anyString());
//       ^---lambda--^

Other than with Mockito matchers (through really counterintuitive hacks), Mockito doesn't get special treatment in its Java syntax. If count = 0 and you run what you have, then this is exactly and only what Mockito will see:

doReturn(1).when(mockObject).mockObjectMethod(Mockito.anyString());
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • Using `verify` makes sense, but I don't want the mock object's method body to be executed. I just want to count the number of times its invoked, but do nothing else. Can I combine `verify` with `doNothing`? – user1491636 May 05 '16 at 20:29
  • @user1491636 Absolutely. Erase the existing behavior with `doNothing` and then `verify` the method call count later on. Sorry not to catch that the first time! – Jeff Bowman May 05 '16 at 20:32