How can we replace the method body of a void method of a stub?
Something like this:
interface Foo {
void foo(Integer j);
}
(...)
Foo mockFoo = mock(Foo.class);
Answer<Void> ans = invocation -> {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
};
when(mockFoo.foo(any())).thenAnswer(ans);
(...)
mockFoo.foo(5) // Should print out "called with arguments: [5]"
It is important to be able to access the parameters, and to be able to execute some code that uses those parameters.
We tried doAnswer(ans).when(mockFoo).foo(any());
, but it seems to execute the body of the ans lambda a few times when setting up the mock, and it resets our mockFoo variable to "null" for some weird reason between the .when(mockFoo)
and the .foo(any())
calls.
So effectively:
Foo mockFoo = mock(Foo.class)
// mockFoo is an instance of a Foo$MockitoMock
Foo o = doAnswer(ans).when(mockFoo);
// mockFoo just became null at this point..?!
o.foo(any());
P.S. We are using the VertxUnitRunner
for running the test, but the problem persists with the MockitoJUnitRunner
as well.
Resolved in comments:
You were right. In my actual test I was supplying any() as parameter for an int, which seems to have been the cause. Replacing it with anyInt() fixed the problem.
This is difficult to warn about, because the exception comes from Mockito's default null
value (necessary due to erasure) being automatically unboxed (necessary due to Java 5+ semantics), which is outside of Mockito's control and prior to Mockito knowing which method signature your test is attempting to call. This is also not a Mockito exception, or even an exception that Mockito deliberately invokes, so the error message is difficult to modify with suggestions.
For all uses of Mockito matchers in primitive values, use the appropriate primitive: anyInt
, intThat
, and so forth.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With