Mixing ArgumentMatchers with Real Values
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
Mockito has a strict rule: you can't mix argument matchers like anyString or anyInt with real values like a specific string or number in the same method call.
It's all matchers or all real values—no in-between. If you try to mix them, like when you call findUser with anyString and the number 25, Mockito throws InvalidUseOfMatchersException. The fix is wrapping the real value with eq, so you'd write eq of 25 instead of just 25.
That turns it into a matcher, and now all arguments are matchers, which satisfies the rule. The reason for this rule is how Mockito works internally. Matchers record themselves on a thread-local stack when you call them.
When Mockito processes the stubbing, it pops matchers off that stack to match them with arguments. If you throw in a raw value, it doesn't go on the stack, so the stack size doesn't match the argument count, and Mockito can't figure out which matcher goes with which argument. It's like telling Mockito to use one system for some arguments and another system for others—it just can't handle that.
The rule applies to both when for stubbing and verify for verification, because they use the same matching mechanism. So anytime you need to be flexible on some arguments but exact on others, wrap the exact ones with eq and you're good.
Mixing ArgumentMatchers with Real Values
Direct Answer
You cannot mix argument matchers and real values in the same method call—Mockito requires either all arguments to be matchers or all to be real values. If you need to mix, wrap the real value with eq(value) to turn it into a matcher. This is because matchers use thread-local state, and mixing raw values bypasses that mechanism, causing InvalidUseOfMatchersException.
Code Example
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@Test
void demonstrateMatcherRules() {
// WRONG: Mixing matcher (anyString) with raw value (25)
// when(userRepository.findByNameAndAge(anyString(), 25)) // InvalidUseOfMatchersException
// CORRECT: All matchers - wrap the literal with eq()
when(userRepository.findByNameAndAge(anyString(), eq(25)))
.thenReturn(new User("John", 25));
// CORRECT: All real values - no matchers at all
when(userRepository.findByNameAndAge("Alice", 30))
.thenReturn(new User("Alice", 30));
// CORRECT: Multiple matchers - all arguments are matchers
when(userRepository.findByNameAndAge(anyString(), anyInt()))
.thenReturn(new User("Default", 0));
}
}
Common Mistakes & Pitfalls
- Forgetting eq() and getting InvalidUseOfMatchersException: Freshers write when(mock.method(anyString(), 42)) and the test blows up—they don't realize 42 needs to be wrapped as eq(42) because anyString() put Mockito in matcher mode.
- Using eq() when all arguments are real values: Writing when(mock.method(eq("value"), eq(123))) is unnecessary when you could just write when(mock.method("value", 123))—it's more verbose and harder to read.
- Not understanding why the rule exists: Treating it as arbitrary when it's actually about how Mockito's matcher stack works—knowing the "why" helps you remember the "what".
- Mixing in verify() calls: The same rule applies to verify, not just when—verify(mock).method(any(), 42) also throws InvalidUseOfMatchersException, but freshers often only learn the rule for stubbing.
Check your understanding
Answer these without looking back at the article.
- What is InvalidUseOfMatchersException and what causes it?
- How does Mockito's internal matcher stack work at a high level?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.