In Mockito, you cannot directly combine argument matchers with specific values when stubbing or verifying methods. This is a design choice to ensure clarity and consistency in how arguments are matched. When using argument matchers, all arguments must be specified using matchers. Similarly, when using specific values, all arguments must be specified as exact values.
Why Mixing Matchers and Values Isn't Supported
Mockito requires that either all arguments are specified using matchers or all are specified using exact values. This rule helps prevent ambiguity in how arguments are matched. For example, if you have a method with two parameters and you want to use a matcher for one and a specific value for the other, you cannot do so directly. You must either use matchers for all arguments or specific values for all arguments.
Example of Using Only Matchers
Here's an example where all arguments are specified using matchers:
java
Foo mockFoo = mock(Foo.class);
when(mockFoo.bool(anyString(), anyInt(), any(Object.class))).thenReturn(true);
In this case, `anyString()`, `anyInt()`, and `any(Object.class)` are all matchers.
Example of Using Only Specific Values
If you want to use specific values instead, you would do something like this:
java
Foo mockFoo = mock(Foo.class);
when(mockFoo.bool("specificString", 10, "specificObject")).thenReturn(true);
Here, `"specificString"`, `10`, and `"specificObject"` are specific values.
Workaround for Specific Values with Matchers
If you need to match a specific value for one argument and use a matcher for another, you can use the `eq()` matcher for the specific value. This technically still uses matchers for all arguments but allows you to specify exact values:
java
Foo mockFoo = mock(Foo.class);
when(mockFoo.bool(eq("specificString"), anyInt(), any(Object.class))).thenReturn(true);
In this example, `eq("specificString")` is used to match the string `"specificString"` exactly, while `anyInt()` and `any(Object.class)` are used for the other arguments.
Conclusion
While you cannot mix argument matchers with raw values directly in Mockito, using `eq()` for specific values provides a way to achieve similar functionality while adhering to Mockito's rules. This approach ensures that your tests are clear and consistent in how they handle method arguments.
Citations:[1] https://www.digitalocean.com/community/tutorials/mockito-argument-matchers-any-eq
[2] https://www.toptal.com/java/a-guide-to-everyday-mockito
[3] https://github.com/etorreborre/specs2/issues/854
[4] https://www.softwaretestinghelp.com/mockito-matchers/
[5] https://stackoverflow.com/questions/22822512/how-do-mockito-matchers-work
[6] https://www.scalatest.org/user_guide/using_matchers
[7] https://stackoverflow.com/questions/63481301/can-i-mix-one-matcher-and-1-exact-value-in-mockito-arguments
[8] https://site.mockito.org/javadoc/current/org/mockito/ArgumentMatchers.html