Reputation: 3064
I have this code:
import static org.mockito.Mockito.*;
final Combobox combobox = mock(Combobox.class);
//.... some business logic which calls method 'appendChild' on 'combobox'
verify(combobox, times(3)).appendChild((Component) anyObject()); // <<== exception here
And it writes all the time this:
Invalid use of argument matchers!
2 matchers expected, 1 recorded.
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
appendChild method looks like this:
public final boolean appendChild(Component child)
{
return insertBfr(null, child);
}
Upvotes: 1
Views: 2726
Reputation: 95654
appendChild
is a final method, which means you can't mock or verify it. The Java compiler understands "final" to mean that it can be sure which actual method implementation it's calling, which means it take a shortcut to call that code directly rather than allowing Mockito to sneak in and replace the implementation. In general, this is one of the good reasons people recommend not to mock types you don't own or control.
Refactor your test, or use PowerMockito to perform deep bytecode magic to mock those final methods.
(Why that exception? Matchers actually affect static state in Mockito. Because you call anyObject
on that line, Mockito still registers a Matcher. That Matcher matches a nonexistent argument on your next call to when
or verify
, or gets caught by the Mockito usage validator if you use MockitoJUnitRunner
. Either way, it's a good catch, because the code doesn't do what you think it does.)
Upvotes: 2