Mockito's ArgumentMatchers class offers any(), any(SomeClass.class) and isA(SomeClass.class). How do these three differ in what they will actually match?
answer
- any() = anything incl. null, no type check
- any(Foo.class) == isA(Foo.class) since 2.1.0
- typed matchers exclude null
- instanceof check -> subclasses match, generics erased
- Mockito 1 upgrade: null used to pass
basics
~20 sany() matches absolutely anything, including null, with no type check. any(SomeClass.class) is an alias of isA(SomeClass.class) in Mockito 2 and later: both require a non-null instance of that type (subclasses included). The class argument in any(...) is not just a cast hint.
solid answer
~40 sany() is the unconditional matcher: any value, any type, null included. It exists mostly to satisfy generics without a cast. any(SomeClass.class) and isA(SomeClass.class) are the type-checked matchers - the argument must be a non-null instance of SomeClass or a subclass. Since Mockito 2.1.0 any(Class) is documented as an alias of isA(Class); in Mockito 1.x it did no type check and matched null, so old code and old blog posts read differently. Practical consequences: any(String.class) will not match a null argument, so a passing test can start failing after a Mockito 1 to 2 upgrade; and because the check is instanceof, any(Number.class) matches an Integer argument. When you need null accepted, use any() or nullable(String.class) explicitly. Because of type erasure, any(List.class) cannot distinguish List<String> from List<Long>.
code
java · 5 linesverify(handler).handle(isA(TimeoutException.class));
verify(repo).save(any());
verify(cache).put(any(String.class), any(Session.class));go deeper
Know that any() takes anything including null and that any(Foo.class) requires a non-null Foo. One correct sentence each is enough.
State the alias relationship with isA, the Mockito 2.1.0 null change, and that the check is instanceof so subclasses match and generics do not.
Bring the upgrade symptom - null arguments silently accepted under Mockito 1 - and the case where isA is a genuine assertion, such as exception types.
Discuss it as a suite-wide safety default: tightening null semantics surfaced real production bugs, which is the argument for preferring typed matchers as the house style.
## The three matchers side by side - any() - returns (T) null after registering a matcher that always answers true. No type check, no null check. It matches a null argument, a String, a Map, anything. - any(Class<T> type) - registers a matcher that answers true only when the argument is non-null and passes an instanceof check against the given class. - isA(Class<T> type) - same behaviour, older name, and the semantics any(Class) delegates to. The Mockito javadoc for any(Class) says plainly that it matches any object of the given type excluding nulls, and that it is an alias of isA. So in modern Mockito the only real distinction is naming taste: isA reads as a type assertion, any(Foo.class) reads as 'I do not care which Foo'. ## The Mockito 1 to 2 change that trips people In Mockito 1.x, any(Foo.class) ignored the class entirely. The class literal was only there to help the compiler infer T, and null matched happily. Mockito 2.1.0 deliberately tightened this so tests would be safer, and the same change made anyString(), anyList(), anyMap() and the rest reject null. The practical symptom on upgrade is a verification that used to pass now failing with 'Argument(s) are different!' where the actual argument is null - the production code was always passing null and the old matcher hid it. ## Erasure limits the type check The check is a runtime instanceof, so generics are invisible: any(List.class) matches List<String> and List<Long> alike, and there is no matcher that can tell them apart. Likewise the check is polymorphic - any(Number.class) matches an Integer, and any(Object.class) matches every non-null argument, which makes it a slightly stricter any(). ## Choosing between them Use any() when the parameter is generic and you truly do not care, or when null is a legitimate value you want to accept. Use any(Foo.class) or isA(Foo.class) when the method is overloaded or the parameter type carries meaning - for instance verify(handler).handle(isA(TimeoutException.class)) is a real assertion, because it fails if the code wrapped the cause in a different exception type. That is the one case where the type-checked matcher earns its keep as an assertion rather than a placeholder. ## A note on overload resolution Because the class literal drives generic inference, any(Foo.class) is also the way to disambiguate when the mocked method is overloaded, for example handle(String) versus handle(Event). Writing any() there may not compile or may bind to the wrong overload; passing the class literal makes the intent explicit to the compiler as well as to Mockito. ## Varargs caveat Vararg parameters have their own history in Mockito, and the exact arity that any() versus any(Foo.class) matches has changed across major versions. If you are matching a vararg method, pin down the behaviour on your version with a quick test rather than trusting memory.
- A test that passed on Mockito 1.10 fails after upgrading to Mockito 5 with 'Argument(s) are different', and the actual argument shown is null. What changed?Mockito 2.1.0 made typed matchers reject null: any(Foo.class), anyString(), anyList() and friends now require a non-null argument. The production code was already passing null; the old matcher simply accepted it. Either fix the code if the null is a bug, or express the intent explicitly with isNull() or nullable(Foo.class).
- Can you write a matcher that distinguishes List<String> from List<Integer>?Not through the type check, because generics are erased at runtime and any(List.class) only performs instanceof. The only way is to inspect the elements at runtime, which means a predicate over the actual list contents rather than a type-based matcher.
saying these in an interview costs you the question
- Saying the class literal in any(Foo.class) is only a cast hint - true in Mockito 1, false since 2.1.0
- Claiming any(Foo.class) matches null
- Believing isA is stricter than any(Class) in modern Mockito
- Expecting any(List.class) to distinguish generic type parameters
- Assuming any(Object.class) is identical to any() - it rejects null