| /* |
| * Copyright (c) 2016 Mockito contributors |
| * This program is made available under the terms of the MIT License. |
| */ |
| package org.mockito; |
| |
| /** |
| * 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. |
| * <p> |
| * For non-trivial method arguments used in stubbing or verification, you have following options |
| * (in no particular order): |
| * <ul> |
| * <li>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! |
| * </li> |
| * <li>don't match the argument strictly, just use one of the lenient argument matchers like |
| * {@link Mockito#notNull()}. Some times it is better to have a simple test that works than |
| * a complicated test that seem to work. |
| * </li> |
| * <li>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. |
| * </li> |
| * <li>use {@link 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. |
| * </li> |
| * <li>use customized argument matchers by implementing {@link ArgumentMatcher} interface |
| * and passing the implementation to the {@link Mockito#argThat} method. |
| * This option is useful if custom matcher is needed for stubbing and can be reused a lot. |
| * Note that {@link Mockito#argThat} demonstrates <b>NullPointerException</b> auto-unboxing caveat. |
| * </li> |
| * <li>use an instance of hamcrest matcher and pass it to |
| * {@link org.mockito.hamcrest.MockitoHamcrest#argThat(org.hamcrest.Matcher)} |
| * Useful if you already have a hamcrest matcher. Reuse and win! |
| * Note that {@link org.mockito.hamcrest.MockitoHamcrest#argThat(org.hamcrest.Matcher)} demonstrates <b>NullPointerException</b> auto-unboxing caveat. |
| * </li> |
| * <li>Java 8 only - use a lambda in place of an {@link ArgumentMatcher} since {@link ArgumentMatcher} |
| * is effectively a functional interface. A lambda can be used with the {@link Mockito#argThat} method.</li> |
| * </ul> |
| * |
| * <p> |
| * Implementations of this interface can be used with {@link Matchers#argThat} method. |
| * Use <code>toString()</code> method for description of the matcher |
| * - it is printed in verification errors. |
| * |
| * <pre class="code"><code class="java"> |
| * 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())); |
| * </code></pre> |
| * |
| * To keep it readable you can extract method, e.g: |
| * |
| * <pre class="code"><code class="java"> |
| * verify(mock).addAll(<b>argThat(new ListOfTwoElements())</b>); |
| * //becomes |
| * verify(mock).addAll(<b>listOfTwoElements()</b>); |
| * </code></pre> |
| * |
| * In Java 8 you can treat ArgumentMatcher as a functional interface |
| * and use a lambda, e.g.: |
| * |
| * <pre class="code"><code class="java"> |
| * verify(mock).addAll(<b>argThat(list -> list.size() == 2)</b>); |
| * </code></pre> |
| * |
| * <p> |
| * Read more about other matchers in javadoc for {@link Matchers} class. |
| * <h2>2.1.0 migration guide</h2> |
| * |
| * All existing custom implementations of <code>ArgumentMatcher</code> will no longer compile. |
| * All locations where hamcrest matchers are passed to <code>argThat()</code> will no longer compile. |
| * There are 2 approaches to fix the problems: |
| * <ul> |
| * <li>a) Refactor the hamcrest matcher to Mockito matcher: |
| * Use "implements ArgumentMatcher" instead of "extends ArgumentMatcher". |
| * Then refactor <code>describeTo()</code> method into <code>toString()</code> method. |
| * </li> |
| * <li> |
| * b) Use <code>org.mockito.hamcrest.MockitoHamcrest.argThat()</code> instead of <code>Mockito.argThat()</code>. |
| * Ensure that there is <a href="http://hamcrest.org/JavaHamcrest/">hamcrest</a> dependency on classpath |
| * (Mockito does not depend on hamcrest any more). |
| * |
| * </li> |
| * </ul> |
| * What option is right for you? If you don't mind compile dependency to hamcrest |
| * then option b) is probably right for you. |
| * Your choice should not have big impact and is fully reversible - |
| * you can choose different option in future (and refactor the code) |
| * |
| * @param <T> type of argument |
| * @since 2.1.0 |
| */ |
| public interface ArgumentMatcher<T> { |
| |
| /** |
| * Informs if this matcher accepts the given argument. |
| * <p> |
| * The method should <b>never</b> assert if the argument doesn't match. It |
| * should only return false. |
| * <p> |
| * See the example in the top level javadoc for {@link ArgumentMatcher} |
| * |
| * @param argument |
| * the argument |
| * @return true if this matcher accepts the given argument. |
| */ |
| boolean matches(T argument); |
| } |