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 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 theArgumentMatchers.argThat(org.mockito.ArgumentMatcher<T>)
method. This option is useful if custom matcher is needed for stubbing and can be reused a lot. Note thatArgumentMatchers.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 thatMockitoHamcrest.argThat(org.hamcrest.Matcher)
demonstrates NullPointerException auto-unboxing caveat. - Java 8 only - use a lambda in place of an
ArgumentMatcher
sinceArgumentMatcher
is effectively a functional interface. A lambda can be used with theArgumentMatchers.argThat(org.mockito.ArgumentMatcher<T>)
method.
Implementations of this interface can be used with
ArgumentMatchers.argThat(org.mockito.ArgumentMatcher<T>)
method. UsetoString()
method for description of the matcher - it is printed in verification errors.
To keep it readable you can extract method, e.g: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()));
In Java 8 you can treat ArgumentMatcher as a functional interface and use a lambda, e.g.:verify(mock).addAll(argThat(new ListOfTwoElements())); //becomes verify(mock).addAll(listOfTwoElements());
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 ofArgumentMatcher
will no longer compile. All locations where hamcrest matchers are passed toargThat()
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 intotoString()
method. -
b) Use
org.mockito.hamcrest.MockitoHamcrest.argThat()
instead ofMockito.argThat()
. Ensure that there is hamcrest dependency on classpath (Mockito does not depend on hamcrest any more).
- Since:
- 2.1.0
-
-
Method Summary
All Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description boolean
matches(T argument)
Informs if this matcher accepts the given argument.default Class<?>
type()
The type of the argument this matcher matches.
-
-
-
Method Detail
-
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.
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:
- 5.0.0
-
-