I have a class where I want a method stubbed out, but I want to see what argument was passed to that stubbed method. However, I won't be invoking the method directly in the test, but instead invoking something that will eventually call it. So far, examples I've found for verifying arguments is only for methods that are directly invoked.
Here's an example that illustrates the problem:
public class FooTest
{
@Test
public void testFoo()
{
Foo foo = mock(Foo.class);
when(foo.mockableMethod(anyString())).thenReturn("dummy");
foo.parentMethod(true);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(foo).mockableMethod(captor.capture());
assertEquals("foo", captor.getValue());
}
class Foo
{
public void parentMethod(boolean isFoo)
{
mockableMethod(isFoo ? "foo" : "bar");
}
protected String mockableMethod(String passedArgument)
{
// Only returning for brevity; assume it does a lot more.
return passedArgument;
}
}
}
This yields the following error:
junit.framework.AssertionFailedError:
Wanted but not invoked:
foo.mockableMethod(<Capturing argument>);
-> at FooTest.testFoo(FooTest.java:32)
However, there were other interactions with this mock:
foo.parentMethod("foo");
-> at FooTest.testFoo(FooTest.java:29)
Is this even possible? This setup works just fine if I verify parentMethod
instead of mockableMethod
, but that's not very useful for me. In this example, I specifically want to make sure that the stubbed method mockableMethod
is called with "foo" if parentMethod
is called with true
.
The only alternative I can think of is doing something like this within testFoo
:
when(foo.mockableMethod("foo")).thenReturn("dummy");
... but I'm not sure how to catch the case where an argument other than "foo" is sent to it. thenThrow
and fail on that? Suggestions welcome!