1/*
2 * Copyright (c) 2016 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5package org.mockito;
6
7/**
8 * Allows creating customized argument matchers.
9 * This API was changed in Mockito 2.1.0 in an effort to decouple Mockito from Hamcrest
10 * and reduce the risk of version incompatibility.
11 * Migration guide is included close to the bottom of this javadoc.
12 * <p>
13 * For non-trivial method arguments used in stubbing or verification, you have following options
14 * (in no particular order):
15 * <ul>
16 *     <li>refactor the code so that the interactions with collaborators are easier to test with mocks.
17 *     Perhaps it is possible to pass a different argument to the method so that mocking is easier?
18 *     If stuff is hard to test it usually indicates the design could be better, so do refactor for testability!
19 *     </li>
20 *     <li>don't match the argument strictly, just use one of the lenient argument matchers like
21 *     {@link Mockito#notNull()}. Some times it is better to have a simple test that works than
22 *     a complicated test that seem to work.
23 *     </li>
24 *     <li>implement equals() method in the objects that are used as arguments to mocks.
25 *     Mockito naturally uses equals() for argument matching.
26 *     Many times, this is option is clean and simple.
27 *     </li>
28 *     <li>use {@link ArgumentCaptor} to capture the arguments and perform assertions on their state.
29 *     Useful when you need to verify the arguments. Captor is not useful if you need argument matching for stubbing.
30 *     Many times, this option leads to clean and readable tests with fine-grained validation of arguments.
31 *     </li>
32 *     <li>use customized argument matchers by implementing {@link ArgumentMatcher} interface
33 *     and passing the implementation to the {@link Mockito#argThat} method.
34 *     This option is useful if custom matcher is needed for stubbing and can be reused a lot.
35 *     Note that {@link Mockito#argThat} demonstrates <b>NullPointerException</b> auto-unboxing caveat.
36 *     </li>
37 *     <li>use an instance of hamcrest matcher and pass it to
38 *     {@link org.mockito.hamcrest.MockitoHamcrest#argThat(org.hamcrest.Matcher)}
39 *     Useful if you already have a hamcrest matcher. Reuse and win!
40 *     Note that {@link org.mockito.hamcrest.MockitoHamcrest#argThat(org.hamcrest.Matcher)} demonstrates <b>NullPointerException</b> auto-unboxing caveat.
41 *     </li>
42 *     <li>Java 8 only - use a lambda in place of an {@link ArgumentMatcher} since {@link ArgumentMatcher}
43 *     is effectively a functional interface. A lambda can be used with the {@link Mockito#argThat} method.</li>
44 * </ul>
45 *
46 * <p>
47 * Implementations of this interface can be used with {@link Matchers#argThat} method.
48 * Use <code>toString()</code> method for description of the matcher
49 * - it is printed in verification errors.
50 *
51 * <pre class="code"><code class="java">
52 * class ListOfTwoElements implements ArgumentMatcher&lt;List&gt; {
53 *     public boolean matches(List list) {
54 *         return list.size() == 2;
55 *     }
56 *     public String toString() {
57 *         //printed in verification errors
58 *         return "[list of 2 elements]";
59 *     }
60 * }
61 *
62 * List mock = mock(List.class);
63 *
64 * when(mock.addAll(argThat(new ListOfTwoElements))).thenReturn(true);
65 *
66 * mock.addAll(Arrays.asList(&quot;one&quot;, &quot;two&quot;));
67 *
68 * verify(mock).addAll(argThat(new ListOfTwoElements()));
69 * </code></pre>
70 *
71 * To keep it readable you can extract method, e.g:
72 *
73 * <pre class="code"><code class="java">
74 *   verify(mock).addAll(<b>argThat(new ListOfTwoElements())</b>);
75 *   //becomes
76 *   verify(mock).addAll(<b>listOfTwoElements()</b>);
77 * </code></pre>
78 *
79 * In Java 8 you can treat ArgumentMatcher as a functional interface
80 * and use a lambda, e.g.:
81 *
82 * <pre class="code"><code class="java">
83 *   verify(mock).addAll(<b>argThat(list -> list.size() == 2)</b>);
84 * </code></pre>
85 *
86 * <p>
87 * Read more about other matchers in javadoc for {@link Matchers} class.
88 * <h2>2.1.0 migration guide</h2>
89 *
90 * All existing custom implementations of <code>ArgumentMatcher</code> will no longer compile.
91 * All locations where hamcrest matchers are passed to <code>argThat()</code> will no longer compile.
92 * There are 2 approaches to fix the problems:
93 * <ul>
94 * <li>a) Refactor the hamcrest matcher to Mockito matcher:
95 * Use "implements ArgumentMatcher" instead of "extends ArgumentMatcher".
96 * Then refactor <code>describeTo()</code> method into <code>toString()</code> method.
97 * </li>
98 * <li>
99 * b) Use <code>org.mockito.hamcrest.MockitoHamcrest.argThat()</code> instead of <code>Mockito.argThat()</code>.
100 * Ensure that there is <a href="http://hamcrest.org/JavaHamcrest/">hamcrest</a> dependency on classpath
101 * (Mockito does not depend on hamcrest any more).
102 *
103 * </li>
104 * </ul>
105 * What option is right for you? If you don't mind compile dependency to hamcrest
106 * then option b) is probably right for you.
107 * Your choice should not have big impact and is fully reversible -
108 * you can choose different option in future (and refactor the code)
109 *
110 * @param <T> type of argument
111 * @since 2.1.0
112 */
113public interface ArgumentMatcher<T> {
114
115    /**
116     * Informs if this matcher accepts the given argument.
117     * <p>
118     * The method should <b>never</b> assert if the argument doesn't match. It
119     * should only return false.
120     * <p>
121     * See the example in the top level javadoc for {@link ArgumentMatcher}
122     *
123     * @param argument
124     *            the argument
125     * @return true if this matcher accepts the given argument.
126     */
127    boolean matches(T argument);
128}
129