Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon How do you decide when to use raw values versus matchers in Mockito


How do you decide when to use raw values versus matchers in Mockito


When using Mockito for unit testing, deciding whether to use raw values or matchers depends on the specific requirements of your test scenario. Here's a detailed explanation to help guide your decision:

Raw Values

Use Cases:
- Specific Behavior: Use raw values when you want to test a specific behavior of your method with exact input parameters. This ensures that your test is precise and only passes if the method behaves as expected with those exact inputs.
- Equality Matching: Raw values are implicitly matched using `eq()` by Mockito, meaning that if you pass a raw value, Mockito will automatically use an equality matcher (`eq()`) for it. This is useful when you want to ensure that the method is called with a specific value.

Example:

java
Mockito.when(mockFoo.bool("false", 10, new Object())).thenReturn(false);

In this case, the method `bool()` will only return `false` if it is called with the exact string `"false"`, the integer `10`, and the specific object instance `new Object()`.

Matchers

Use Cases:
- Generic Behavior: Use matchers when you want to test a generic behavior of your method, regardless of the specific input values. This is particularly useful when you're testing that a method is called, but you don't care about the exact values passed to it.
- Flexibility: Matchers provide flexibility in your tests. For example, you can use `anyString()`, `anyInt()`, or `any()` to match any value of a specific type. This makes your tests less brittle and more focused on the overall functionality rather than specific input values.

Example:

java
Mockito.when(mockFoo.bool(anyString(), anyInt(), any(Object.class))).thenReturn(true);

Here, the method `bool()` will return `true` regardless of the string, integer, or object passed to it.

Mixing Raw Values and Matchers

**Important Rule: When using matchers, all arguments must be provided by matchers. You cannot mix raw values with matchers in the same method call. If you need to specify a specific value while using matchers for other arguments, use the `eq()` matcher explicitly for the specific value.

Example:

java
Mockito.when(mockFoo.bool(eq("false"), anyInt(), any(Object.class))).thenReturn(false);

In this example, the method `bool()` will return `false` if it is called with the string `"false"`, any integer, and any object.

Choosing Between Raw Values and Matchers

- Test Specificity: If your test requires a specific input to validate a particular behavior, use raw values. If you're testing a more generic scenario where the exact input doesn't matter, use matchers.
- Test Robustness: Using matchers can make your tests more robust by reducing their dependency on specific input values. However, if the method's behavior is tightly coupled with specific inputs, raw values might be more appropriate.
- Readability and Maintainability: Consider the readability and maintainability of your tests. If a test is overly complex due to many specific raw values, using matchers might simplify it and make it easier to understand.

Ultimately, the choice between raw values and matchers in Mockito depends on the specific requirements of your test scenario and your testing strategy.

Citations:
[1] https://www.digitalocean.com/community/tutorials/mockito-argument-matchers-any-eq
[2] https://stackoverflow.com/questions/14845690/mockito-invaliduseofmatchersexception
[3] https://github.com/etorreborre/specs2/issues/854
[4] https://stackoverflow.com/questions/73046134/when-should-i-use-argument-matcher-or-passing-argument-directly-when-mockito-uni
[5] https://groups.google.com/g/okapi-devel/c/ptHE4rU8VVM
[6] https://www.softwaretestinghelp.com/mockito-matchers/
[7] https://groups.google.com/g/mockito/c/g5Lo53dH-Cs
[8] https://github.com/mockito/mockito/issues/1970
[9] https://www.lambdatest.com/automation-testing-advisor/selenium/methods/org.mockito.ArgumentMatchers.isNull
[10] https://groups.google.com/g/mockito/c/I-_kuURopFw