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<List> { 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("one", "two")); 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 */ matches(T argument)127 boolean matches(T argument); 128 } 129