Reputation: 440
import org.mockito.Mockito;
public class Scratch2 {
public static class Foo {
}
public interface Custom {
public void someMethod(String arg1, String arg2, String arg3,
String arg4);
}
public static class SomeClass {
private final Custom custom;
public SomeClass(Custom c) {
this.custom = c;
}
public boolean run(Foo someFoo) {
custom.someMethod("Dummy", "Dummy", "Dummy", "Dummy");
return false;
}
}
public static void callSomeMethod(Custom custom) {
custom.someMethod("Dummy", "Dummy", "Dummy", "Dummy");
}
public static void main(String[] args) {
Custom mock = Mockito.mock(Custom.class);
SomeClass c = new SomeClass(mock);
callSomeMethod(Mockito.mock(Custom.class));
c.run(Mockito.any(Foo.class));
}
}
If we mock the custom interface and call someMethod on it directly there is no problem. But using the run() gives the following error:
==========
Exception in thread "main" org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers! 4 matchers expected, 1 recorded: -> at com.knewton.scratch.Scratch2.main(Scratch2.java:37)
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.
at com.knewton.scratch.Scratch2$SomeClass.run(Scratch2.java:24) at com.knewton.scratch.Scratch2.main(Scratch2.java:37)
===========
This is on mockito 1.9.5
Upvotes: 1
Views: 2802
Reputation: 8492
Your use of the matcher in this case is not correct. What happens is that mockito will record this matcher to use in a future call to a mocked method, which in your case happens here:
public boolean run(Foo someFoo) {
custom.someMethod("Dummy", "Dummy", "Dummy", "Dummy"); // <- call on mock
return false;
}
mockito counts your use of Mockito.any(Foo.class)
for this method and now rightly complains that you only provided one matcher, but in fact, since the method requires 4 parameters, you need to pass 4 matchers.
Instead of passing a matcher to your run()
method you should instead either pass a real instance (as you do in your own answer), or if that object is hard to instantiate and you don't need it anyway, you can replace it by a mock:
public static void main(String[] args) {
Custom mock = Mockito.mock(Custom.class);
SomeClass c = new SomeClass(mock);
c.run(Mockito.mock(Foo.class));
}
Upvotes: 1
Reputation: 440
So here is how I worked around it and its weird. Its definitely a bug.
import org.mockito.Mockito;
public class Scratch2 {
public static class Foo {
}
public interface Custom {
public void someMethod(String arg1, String arg2, String arg3,
String arg4);
}
public static class SomeClass {
private final Custom custom;
public SomeClass(Custom c) {
this.custom = c;
}
public boolean run(Foo serviceDiscoveryConfig) {
custom.someMethod("Dummy", "Dummy", "Dummy", "Dummy");
return false;
}
}
public static void main(String[] args) {
Custom mock = Mockito.mock(Custom.class);
SomeClass c = new SomeClass(mock);
Foo foo = new Foo();// HAD TO MAKE A NEW OBJECT HERE!
c.run(foo);
}
}
Upvotes: 0