Mockito Argument Matchers: Using any(), eq(), ArgumentCaptor, and Custom Matchers

Mockito argument matchers allow you to stub and verify method calls without hard-coding every argument value. Combined with when() and verify(), matchers let you define conditions such as “any string” or “this exact ID” while keeping tests easy to read. This guide covers built-in matchers, the consistency rule that avoids InvalidUseOfMatchersException, ArgumentCaptor, and custom ArgumentMatcher implementations with current Mockito 5.x APIs and JUnit 5.

Key Takeaways

  • Mockito argument matchers are available in org.mockito.ArgumentMatchers and should only be used inside when(), verify(), and related stubbing helpers such as doNothing().when().
  • When one parameter uses a matcher, every parameter in the same method call must also use a matcher. Use eq() around literal values instead of passing those values directly.
  • Prefer typed matchers such as anyString(), anyInt(), and anyList() instead of the general any() matcher for primitives and references to reduce null and unboxing issues.
  • Use ArgumentCaptor when you want to examine the value that was actually passed after a call. Use argThat() together with a custom ArgumentMatcher when reusable inline matching logic is required.
  • Matchers store expectations on an internal stack and return placeholder values, so they should never be called outside a stubbing or verification expression.

Prerequisites

  1. Java 11 or a newer release. If a local runtime is required, follow an appropriate Java installation guide for your operating system.
  2. A Maven or Gradle project configured with JUnit 5 and Mockito 5.x. The examples use Mockito 5.14.2 and JUnit Jupiter 5.10.2.
  3. Basic familiarity with Mockito mocks and method verification.
  4. Optional background knowledge of JUnit 5 and general Mockito usage.

Maven test dependencies:

<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter</artifactId>
  <version>5.10.2</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-junit-jupiter</artifactId>
  <version>5.14.2</version>
  <scope>test</scope>
</dependency>

Statically import the matchers in your test classes:

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

What Are Mockito Argument Matchers?

Mockito argument matchers are utility methods that define flexible conditions for parameters during method stubbing or verification. Rather than requiring an exact value through equals(), a matcher can accept any String, any positive int, or a value that follows a custom domain-specific condition.

How Argument Matchers Work in Mockito

Mockito places matchers on an internal stack while a stub or verification expression is being constructed. Methods such as anyInt() return safe placeholder values, such as 0 for anyInt(), allowing the Java compiler to accept expressions such as when(mock.get(anyInt())). Mockito performs the actual comparison later by applying the stored matchers to the arguments received during a real invocation. Additional details are available in the ArgumentMatchers Javadoc.

When to Use Matchers Instead of Exact Values

Use exact values, or eq(), when a test depends on one particular input. Use matchers when the exact value is unimportant, changes between cases, or follows a recognizable condition such as a type, range, or substring. Excessive use of any() may conceal defects, so exact values are a good default and matchers are best used when they meaningfully reduce repetition.

The following sample class is used throughout the examples:

public class Foo {
    public boolean bool(String str, int i, Object obj) {
        return false;
    }

    public int in(boolean b, java.util.List<String> strs) {
        return 0;
    }

    public int bar(byte[] bytes, String[] s, int i) {
        return 0;
    }

    public void log(String message) {
        // no-op
    }
}

The Mockito Argument Matcher Consistency Rule

Mockito requires all parameters in a particular stubbing or verification call to use matchers, or none of them to use matchers. Combining a matcher with an unwrapped literal results in InvalidUseOfMatchersException.

Why Matchers and Exact Values Cannot Be Mixed

Matcher arguments and literal values are processed through different internal mechanisms in Mockito. For example, when(mock.bool(anyString(), 1, any())) is invalid because 1 is a direct value while the remaining parameters are matchers.

Incorrect:

when(mockFoo.bool(anyString(), 1, any(Object.class))).thenReturn(true); // throws

Correct:

when(mockFoo.bool(anyString(), eq(1), any(Object.class))).thenReturn(true);

The identical requirement applies to verify():

verify(mockFoo).bool(eq("hello"), anyInt(), any(Object.class));

How to Resolve InvalidUseOfMatchersException

  1. Wrap each literal in a matcher such as eq(), eq(1), or eq("hello").
  2. Alternatively, remove all matchers and provide only concrete argument values.
  3. Do not save matcher return values in variables for reuse in later stubbing expressions.

Built-In Mockito Argument Matchers

The following table lists commonly used matchers in Mockito 5.x. Typed reference matchers such as anyString() do not accept null. For nullable arguments, use isNull() or isNotNull().

Matcher Accepted Types Null Behavior Typical Use Case
any() Any reference, varargs Allows null Flexible reference matching
any(Class<T>) Type T Excludes null Type-safe object matching
eq(value) Same type as value Uses equals() behavior Exact values within matcher expressions
anyString() String Excludes null Any non-null string
anyInt() int or Integer Excludes a null wrapper Primitive or boxed integers
anyList() List Excludes null Any non-null list
isNull() / isNotNull() Reference types Explicit null matching Nullable arguments
contains(), startsWith(), endsWith() String Excludes null Partial string comparisons

Using any() and any(Class) for Type-Based Matching

any() accepts any object reference, including null, and also supports varargs. any(Foo.class) checks the expected type and does not match null. Use any(Class) when an explicit type makes the test clearer.

Foo mockFoo = mock(Foo.class);
when(mockFoo.bool(anyString(), anyInt(), any(Object.class))).thenReturn(true);

assertTrue(mockFoo.bool("A", 1, "A"));
assertTrue(mockFoo.bool("B", 10, new Object()));

For array parameters, provide the relevant array class:

when(mockFoo.bar(any(byte[].class), any(String[].class), anyInt())).thenReturn(1);

Using eq() for Exact Values Inside Matcher Chains

If any argument in a call uses a matcher, wrap values that must remain exact with eq():

when(mockFoo.bool(eq("false"), anyInt(), any(Object.class))).thenReturn(false);
assertFalse(mockFoo.bool("false", 10, new Object()));

If no other argument uses a matcher, direct values are allowed: when(mockFoo.bool("false", 10, obj)).

Using anyString(), anyInt(), anyList(), and Other Typed Matchers

Typed matchers make tests easier to understand and help avoid autoboxing problems with primitive parameters:

when(mockFoo.in(anyBoolean(), anyList())).thenReturn(10);

Mockito also provides collection matchers such as anySet(), anyMap(), and anyCollection().

Using isNull() and isNotNull()

when(mockFoo.bool(isNull(), anyInt(), isNotNull())).thenReturn(true);
assertTrue(mockFoo.bool(null, 1, "payload"));

Using contains(), startsWith(), and endsWith() for String Matching

when(mockFoo.bool(startsWith("ERR"), anyInt(), any())).thenReturn(false);
mockFoo.bool("ERR-404", 0, null);
verify(mockFoo).bool(contains("ERR"), anyInt(), any());

Using Mockito Argument Matchers with when() for Stubbing

Stubbing with any() and eq() Together

Foo mockFoo = mock(Foo.class);
when(mockFoo.bool(anyString(), anyInt(), any(Object.class))).thenReturn(true);
when(mockFoo.bool(eq("false"), anyInt(), any(Object.class))).thenReturn(false);

Mockito evaluates stubs according to their declaration order. When matching patterns overlap, place the more specific stub after the broader one.

Stubbing Methods with Multiple Parameters and Void Methods

For a void method, use doNothing(); argument matchers behave in the same way:

doNothing().when(mockFoo).log(anyString());
mockFoo.log("ready");

Using Mockito Argument Matchers with verify() for Behavior Verification

Argument matchers are designed for verify() and stubbing APIs. They are not general-purpose boolean expressions.

Verifying a Method Call with Specific Parameter Types

verify(mockFoo, atLeastOnce()).bool(anyString(), anyInt(), any(Object.class));
verify(mockFoo).bool(eq("false"), anyInt(), any(Object.class));

Combining verify() with times(), never(), and atLeast()

verify(mockFoo, times(1)).log(anyString());
verify(mockFoo, never()).bool(eq("skip"), anyInt(), any());
verify(mockFoo, atLeast(0)).in(anyBoolean(), anyList());

Use InOrder when the order of method calls must also be verified:

InOrder inOrder = inOrder(mockFoo);
inOrder.verify(mockFoo).log(anyString());
inOrder.verify(mockFoo).bool(anyString(), anyInt(), any());

Capturing Mockito Arguments with ArgumentCaptor

ArgumentCaptor stores arguments supplied to a mock so that their real values can be checked afterward. Captors and matchers serve complementary purposes: matchers specify which values are acceptable, while captors make the actual values available for inspection.

When to Use ArgumentCaptor Instead of an Argument Matcher

Choose a captor when several assertions must be performed against the same object after invocation, such as checking fields, collection size, or calculated values. Use a matcher when a predicate is sufficient during stubbing or verification.

ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
mockFoo.log("shipped");
verify(mockFoo).log(messageCaptor.capture());
assertEquals("shipped", messageCaptor.getValue());

ArgumentCaptor with Single and Multiple Invocations

mockFoo.log("first");
mockFoo.log("second");
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mockFoo, times(2)).log(captor.capture());
assertEquals(List.of("first", "second"), captor.getAllValues());

ArgumentCaptor vs Custom ArgumentMatcher

Approach Best For Trade-Off
ArgumentCaptor Examining actual argument instances after a call Requires an additional verification step and is not intended for defining stubbing return values
argThat(ArgumentMatcher) Reusable inline conditions during stubbing or verification Provides less direct visibility into the real value unless verification fails
eq() / typed any*() Simple and concise tests Offers less flexibility for complicated domain-specific conditions

Writing a Custom Mockito ArgumentMatcher

Implement org.mockito.ArgumentMatcher<T> when the built-in matchers cannot express the required condition. Register the custom matching logic through argThat().

Implementing the ArgumentMatcher Interface

import org.mockito.ArgumentMatcher;

public class PremiumOrderMatcher implements ArgumentMatcher<Order> {
    @Override
    public boolean matches(Order order) {
        return order != null && order.getTotalCents() >= 10_000;
    }
}

Custom ArgumentMatcher Example with a Domain Object

public class Order {
    private final int totalCents;
    public Order(int totalCents) { this.totalCents = totalCents; }
    public int getTotalCents() { return totalCents; }
}

public class OrderService {
    public boolean isPremium(Order order) {
        return order != null && order.getTotalCents() >= 10_000;
    }
}

Registering and Using a Custom ArgumentMatcher in Tests

OrderService service = mock(OrderService.class);
when(service.isPremium(argThat(new PremiumOrderMatcher()))).thenReturn(true);
assertTrue(service.isPremium(new Order(15_000)));

A lambda can also be used with Java 8 and newer:

when(service.isPremium(argThat(o -> o.getTotalCents() > 5_000))).thenReturn(true);

Refer to the ArgumentMatcher Javadoc for additional design guidance from the Mockito team.

Mockito AdditionalMatchers

org.mockito.AdditionalMatchers contains additional helpers for numeric comparisons and array equality:

import static org.mockito.AdditionalMatchers.*;

when(mockFoo.bar(any(byte[].class), aryEq(new String[] { "A", "B" }), gt(10))).thenReturn(11);

assertEquals(11, mockFoo.bar("abc".getBytes(), new String[] { "A", "B" }, 20));

Other available helpers include lt(), or(), and(), and not() for combining or defining additional conditions.

Common Mockito Argument Matcher Mistakes and How to Avoid Them

Mixing Matchers with Raw Values

Whenever one parameter uses a matcher, convert any literal parameters in the same call with eq().

Using Argument Matchers Outside when() or verify()

String value = anyString(); // wrong: matcher used outside stub/verify

Matchers need to appear directly inside the mocked method invocation supplied to when() or verify().

Overusing any() and Hiding Real Bugs

For business-critical parameters such as identifiers or currencies, prefer exact values. Matchers should remove unnecessary test noise rather than eliminate meaningful assertions.

Mockito Argument Matchers vs Hamcrest Matchers

Mockito stopped depending directly on Hamcrest in Mockito 2.1. When Hamcrest integration is required, add the mockito-hamcrest artifact and use MockitoHamcrest.argThat(org.hamcrest.Matcher) rather than deprecated org.mockito.Matchers APIs. In most projects, Mockito’s built-in matchers together with argThat(ArgumentMatcher) provide a simpler solution without requiring an additional dependency.

Tool Entry Point When to Choose It
Mockito ArgumentMatchers any(), eq(), contains() The default option for Mockito tests
Custom ArgumentMatcher with argThat() argThat(predicate) Domain-specific matching rules reused across tests
Hamcrest through MockitoHamcrest MockitoHamcrest.argThat(hasItem(...)) Existing Hamcrest assertions already maintained by the project

Choosing the Right Mockito Matching Tool

Need Use
Ignore a parameter value anyString(), anyInt(), any(MyDto.class)
Require one exact value among other matchers eq("literal")
Inspect the value that was actually passed ArgumentCaptor
Apply a complex reusable rule Custom ArgumentMatcher through argThat()
Stub a void method doNothing().when(mock).method(any())

Mockito Argument Matchers FAQs

1. What Are Argument Matchers in Mockito?

Argument matchers are static methods including anyString(), eq(), and argThat() that define how Mockito should compare parameters during stubbing or verification. They make flexible comparisons possible when exact argument values are unavailable or irrelevant. When one parameter uses a matcher, every parameter in the same invocation must also use a matcher.

2. What Is the Difference Between eq() and any()?

eq(value) requires the supplied argument to equal value according to equals(), or == for primitive values. any() and typed versions such as anyString() accept a broader set of values that meet the relevant type or matching condition. Choose eq() when one specific value must match and use any*() when the exact value is not important.

3. Do All Arguments Have to Use Matchers When One Matcher Is Used?

Yes. Mockito applies matcher consistency to every individual stubbing or verify() call. Combining anyString() with an unwrapped literal produces InvalidUseOfMatchersException. Either wrap direct values with eq() or remove all matchers from that invocation.

4. When Should eq() Be Used in Mockito?

Use eq() when another parameter in the same method call already uses a matcher but one particular parameter needs to match an exact value. If all parameters are ordinary literal values and no matchers are involved, eq() is unnecessary.

5. What Does Mockito any() Do?

any() accepts any object reference, including null, for reference-type parameters. Typed alternatives such as anyInt() and any(Order.class) limit matching to specific primitive types or class instances and, since Mockito 2.1.0, typed matchers exclude null. Typed matchers are generally preferable because they make tests clearer and safer.

Conclusion

Mockito argument matchers make focused unit tests easier to write by allowing flexible parameter conditions during stubbing and verification with any(), eq(), typed matchers, ArgumentCaptor, and custom ArgumentMatcher implementations. Keep the all-or-nothing matcher rule in mind, prefer typed matchers for primitive and collection parameters, and use captors when the actual argument state needs to be inspected after a method call.

Source: digitalocean.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: