Package org.mockito

Interface ArgumentMatcher<T>

Type Parameters:
T - type of argument
Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface ArgumentMatcher<T>
Allows creating customized argument matchers. This API was changed in Mockito 2.1.0 in an effort to decouple Mockito from Hamcrest and reduce the risk of version incompatibility. Migration guide is included close to the bottom of this javadoc.

For non-trivial method arguments used in stubbing or verification, you have the following options (in no particular order):

  • refactor the code so that the interactions with collaborators are easier to test with mocks. Perhaps it is possible to pass a different argument to the method so that mocking is easier? If stuff is hard to test it usually indicates the design could be better, so do refactor for testability!
  • don't match the argument strictly, just use one of the lenient argument matchers like ArgumentMatchers.notNull(). Some times it is better to have a simple test that works than a complicated test that seem to work.
  • implement equals() method in the objects that are used as arguments to mocks. Mockito naturally uses equals() for argument matching. Many times, this is option is clean and simple.
  • use ArgumentCaptor to capture the arguments and perform assertions on their state. Useful when you need to verify the arguments. Captor is not useful if you need argument matching for stubbing. Many times, this option leads to clean and readable tests with fine-grained validation of arguments.
  • use customized argument matchers by implementing ArgumentMatcher interface and passing the implementation to the ArgumentMatchers.argThat(org.mockito.ArgumentMatcher<T>) method. This option is useful if custom matcher is needed for stubbing and can be reused a lot. Note that ArgumentMatchers.argThat(org.mockito.ArgumentMatcher<T>) demonstrates NullPointerException auto-unboxing caveat.
  • use an instance of hamcrest matcher and pass it to MockitoHamcrest.argThat(org.hamcrest.Matcher) Useful if you already have a hamcrest matcher. Reuse and win! Note that MockitoHamcrest.argThat(org.hamcrest.Matcher) demonstrates NullPointerException auto-unboxing caveat.
  • Java 8 only - use a lambda in place of an ArgumentMatcher since ArgumentMatcher is effectively a functional interface. A lambda can be used with the ArgumentMatchers.argThat(org.mockito.ArgumentMatcher<T>) method.

Implementations of this interface can be used with ArgumentMatchers.argThat(org.mockito.ArgumentMatcher<T>) method. Use toString() method for description of the matcher - it is printed in verification errors.


 class ListOfTwoElements implements ArgumentMatcher<List> {
     public boolean matches(List list) {
         return list.size() == 2;
     }
     public String toString() {
         //printed in verification errors
         return "[list of 2 elements]";
     }
 }

 List mock = mock(List.class);

 when(mock.addAll(argThat(new ListOfTwoElements()))).thenReturn(true);

 mock.addAll(Arrays.asList("one", "two"));

 verify(mock).addAll(argThat(new ListOfTwoElements()));
 
To keep it readable you can extract method, e.g:

   verify(mock).addAll(argThat(new ListOfTwoElements()));
   //becomes
   verify(mock).addAll(listOfTwoElements());
 
In Java 8 you can treat ArgumentMatcher as a functional interface and use a lambda, e.g.:

   verify(mock).addAll(argThat(list -> list.size() == 2));
 

Read more about other matchers in javadoc for ArgumentMatchers class.

2.1.0 migration guide

All existing custom implementations of ArgumentMatcher will no longer compile. All locations where hamcrest matchers are passed to argThat() will no longer compile. There are 2 approaches to fix the problems:
  • a) Refactor the hamcrest matcher to Mockito matcher: Use "implements ArgumentMatcher" instead of "extends ArgumentMatcher". Then refactor describeTo() method into toString() method.
  • b) Use org.mockito.hamcrest.MockitoHamcrest.argThat() instead of Mockito.argThat(). Ensure that there is hamcrest dependency on classpath (Mockito does not depend on hamcrest any more).
What option is right for you? If you don't mind having a compile-time dependency for Hamcrest, then the second option is probably right for you. Your choice should not have a big impact and is fully reversible - you can choose different option in future (and refactor the code)!
Since:
2.1.0
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    matches(T argument)
    Informs if this matcher accepts the given argument.
    default Class<?>
    The type of the argument this matcher matches.
  • Method Details

    • matches

      boolean matches(T argument)
      Informs if this matcher accepts the given argument.

      The method should never assert if the argument doesn't match. It should only return false.

      See the example in the top level javadoc for ArgumentMatcher

      Parameters:
      argument - the argument
      Returns:
      true if this matcher accepts the given argument.
    • type

      default Class<?> type()
      The type of the argument this matcher matches.

      This method is used to differentiate between a matcher used to match a raw vararg array parameter from a matcher used to match a single value passed as a vararg parameter.

      Where the matcher:

      • is at the parameter index of a vararg parameter
      • is the last matcher passed
      • this method returns a type assignable to the vararg parameter's raw type, i.e. its array type.
      ...then the matcher is matched against the raw vararg parameter, rather than the first element of the raw parameter.

      For example:

      
        // Given vararg method with signature:
        int someVarargMethod(String... args);
      
        // The following will match invocations with any number of parameters, i.e. any number of elements in the raw array.
        mock.someVarargMethod(isA(String[].class));
      
        // The following will match invocations with a single parameter, i.e. one string in the raw array.
        mock.someVarargMethod(isA(String.class));
      
        // The following will match invocations with two parameters, i.e. two strings in the raw array
        mock.someVarargMethod(isA(String.class), isA(String.class));
       

      Only matcher implementations that can conceptually match a raw vararg parameter should override this method.

      Returns:
      the type this matcher handles. The default value of Void means the type is not known.
      Since:
      4.11.0