Home | History | Annotate | Download | only in mockito
      1 /*
      2  * Copyright (c) 2016 Mockito contributors
      3  * This program is made available under the terms of the MIT License.
      4  */
      5 package 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  */
    113 public 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