In Mockito, what is an argument matcher such as any(), anyString() or anyInt(), and why would you stub or verify a call with one instead of passing a concrete expected value?
answer
- literal arg = equals(); matcher = predicate
- ArgumentMatchers: any / anyString / anyInt / eq / same
- any() returns null -> NPE on primitives -> anyInt()
- matchers push onto a thread-local stack
- any() = stability, eq() = precision
basics
~20 sA matcher is a placeholder used inside Mockito's when() or verify() saying 'any argument fitting this description' instead of one exact value. any() matches anything, anyString() any non-null String, anyInt() any int. Use them when the value is irrelevant or unpredictable.
solid answer
~40 sBy default Mockito matches a stubbed or verified call by comparing each argument with equals(). An argument matcher replaces one of those literals with a predicate. The family lives in org.mockito.ArgumentMatchers: any() matches anything including null; any(Foo.class) and isA(Foo.class) match any non-null instance of that type; anyString(), anyList(), anyMap() match any non-null value of that type; anyInt(), anyLong(), anyBoolean() match any value of that primitive; eq(v) and same(v) express equality and identity; isNull(), notNull() and nullable(Foo.class) handle nulls. I use a matcher when the argument is irrelevant to what the test asserts or unpredictable - a generated UUID, a timestamp, an object with no equals(). When the value is the thing under test I pass the real value, because an over-broad any() lets the test keep passing on wrong data.
code
java · 11 linesimport static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
UserRepository repo = mock(UserRepository.class);
when(repo.findByName(anyString())).thenReturn(Optional.empty());
when(repo.countSince(anyLong())).thenReturn(0);
service.register("ada");
verify(repo).save(any(User.class));
verify(repo).audit(eq("REGISTER"), any());go deeper
Know the names and what each matches, and that a plain value means equals(). Show one stubbing and one verification using any() and anyString().
Add the mechanics: matchers push onto a thread-local stack, any() returns null hence the primitive variants, typed matchers exclude null since Mockito 2.
Frame it as a precision-versus-stability decision and say where you insist on exact values - the arguments that carry the behaviour you are testing.
Talk about matcher usage as a team convention: any() as the default makes suites that never fail on wrong data, so set a norm for which arguments must be asserted exactly.
## The default: equals() When you write when(repo.findByName("ada")).thenReturn(user) or verify(repo).findByName("ada"), Mockito compares each argument of the recorded invocation with the value you wrote using equals(). A literal argument means 'equal to this'. ## What a matcher adds An argument matcher swaps that literal for a predicate: instead of 'the argument must equal ada', it says 'the argument must be any non-null String'. The built-ins live in org.mockito.ArgumentMatchers, which Mockito extends, so a static import of either works. - any() - matches literally anything, any type, including null. - any(Foo.class) / isA(Foo.class) - any non-null instance of Foo (type checked). - anyString(), anyList(), anySet(), anyMap(), anyCollection(), anyIterable() - any non-null value of that type. - anyInt(), anyLong(), anyDouble(), anyFloat(), anyShort(), anyByte(), anyChar(), anyBoolean() - any value of that primitive. - eq(v) equality by equals(); same(v) reference identity; refEq(v) field-by-field via reflection. - isNull(), notNull(), nullable(Foo.class). - String helpers: startsWith, endsWith, contains, matches(regex). ## Why the primitive variants exist any() is generic and returns (T) null. If the parameter is a primitive int, Java unboxes that null and throws NullPointerException before Mockito does anything. anyInt() returns 0 instead, so the call compiles and runs. That is the whole reason the primitive family exists; anyInt() matches any int value, it is not a narrower filter than any(). ## How matchers work under the hood A matcher call does not return a usable value. It pushes a matcher object onto a thread-local stack inside Mockito and returns a dummy (null, 0, false). When the mocked method is then invoked inside when(...) or verify(...), Mockito pops that stack and uses the matchers in place of the recorded literal arguments. Two consequences follow: matchers are only meaningful inside stubbing and verification, and calling one anywhere else (in a plain assertion, or to build a value) leaves junk on the stack and blows up later with InvalidUseOfMatchersException, often pointing at an innocent line. ## When to use one, and the cost Use a matcher when the value is genuinely irrelevant to the behaviour under test, or unpredictable: a UUID, Instant.now(), a DTO whose class has no equals(). Use the concrete value when the argument is part of the contract you are asserting. A verification like verify(repo).save(any()) proves only that save was called; it will still pass when the code saves the wrong entity. Matchers trade precision for stability, and every any() you write is precision spent. ## Null behaviour to remember Since Mockito 2.1.0 the typed matchers deliberately exclude null: anyString() will not match a null argument, and neither will any(String.class). Only any(), isNull() and nullable(String.class) accept null. This changed from Mockito 1.x, where those matchers did match null, and it is a frequent source of 'Argument(s) are different' surprises when upgrading.
- Why does Mockito ship anyInt() and anyLong() when any() already matches everything?any() is a generic method that returns (T) null. When the mocked method takes a primitive int, Java has to unbox that null, which throws NullPointerException on the spot. anyInt() returns 0, so the call is safe, and it also documents the parameter type at the call site. Semantically anyInt() still matches any int value.
- What happens if you call a matcher outside when() or verify()?The matcher is pushed onto Mockito's internal thread-local stack and never consumed, so it corrupts the next stubbing or verification. Mockito detects the leftover on a later interaction and throws InvalidUseOfMatchersException or MisusedMatchersException, usually reporting a line that is not where the mistake was. The fix is to only call matchers directly as arguments of the mocked method inside a stubbing or verification.
A literal argument is a passport check against one name; a matcher is a doorman rule - 'anyone with a valid ID' - applied to whoever shows up.
saying these in an interview costs you the question
- Saying anyString() matches null - it has not since Mockito 2.1.0
- Thinking anyInt() is a narrower filter than any() rather than a primitive-safe equivalent
- Using matchers in plain assertions or to build test data
- Claiming any() checks the declared parameter type at runtime
- Defaulting to any() everywhere and calling the resulting test strong