Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon How does Mockito handle raw values versus matchers


How does Mockito handle raw values versus matchers


Mockito is a popular Java framework used for creating mock objects in unit tests. It provides two primary ways to specify arguments when stubbing or verifying method calls: using raw values and using argument matchers.

Raw Values

When you use raw values, Mockito checks if the provided argument is equal to the expected value by calling the `equals()` method internally. This approach is straightforward but can be inflexible if you don't know the exact values beforehand or if you want to test a broader range of inputs.

For example, if you want to stub a method with specific values, you can do it directly without using matchers:

java
Mockito.when(mockObject.method("specificValue1", "specificValue2")).thenReturn("result");

In this case, the method will only return `"result"` when called with exactly `"specificValue1"` and `"specificValue2"`.

Argument Matchers

Argument matchers are static methods provided by Mockito to match method arguments in a more flexible way. They allow you to define reactions for a wider range of values. Common matchers include `any()`, `eq()`, `isNull()`, and others like `gt()`, `lt()`, which are useful for numeric comparisons.

Here's how you might use `any()` to stub a method that should return a value regardless of the input:

java
Mockito.when(mockObject.method(anyString(), anyInt())).thenReturn("result");

In this scenario, the method will return `"result"` for any string and any integer passed as arguments.

Mixing Raw Values and Matchers

Mockito requires that if you use any argument matchers in a method call, all arguments must be provided using matchers. You cannot mix raw values with matchers in the same method call. Attempting to do so will result in an `InvalidUseOfMatchersException`.

For example, the following is incorrect:

java
// Incorrect: Mixing raw value with matcher
Mockito.when(mockObject.method("rawValue", anyInt())).thenReturn("result");

Instead, you should use `eq()` to explicitly specify the raw value as a matcher:

java
// Correct: Using eq() for the raw value
Mockito.when(mockObject.method(eq("rawValue"), anyInt())).thenReturn("result");

Choosing Between Raw Values and Matchers

The choice between using raw values and argument matchers depends on the test scenario:

- Use raw values when you need to test specific inputs and want the test to be precise. This approach ensures that the method behaves correctly for those exact inputs.

- Use argument matchers when you want to test a broader range of inputs or when the exact values are not known or are irrelevant to the test. This approach allows for more flexibility and can simplify your tests by reducing the number of test cases needed.

In summary, Mockito handles raw values and matchers differently, requiring all arguments to be matchers if any are used. The choice between them depends on the specific requirements of your unit tests.

Citations:
[1] https://www.digitalocean.com/community/tutorials/mockito-argument-matchers-any-eq
[2] https://stackoverflow.com/questions/22822512/how-do-mockito-matchers-work
[3] https://www.toptal.com/java/a-guide-to-everyday-mockito
[4] https://stackoverflow.com/questions/73046134/when-should-i-use-argument-matcher-or-passing-argument-directly-when-mockito-uni
[5] https://mockito-python.readthedocs.io/en/latest/the-matchers.html
[6] https://stackoverflow.com/questions/74094043/is-it-recommended-to-use-any-or-a-specific-value-for-unit-tests
[7] https://groups.google.com/g/mockito/c/g5Lo53dH-Cs
[8] https://www.baeldung.com/mockito-argument-matchers