1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6 package org.mockito; 7 8 import org.hamcrest.BaseMatcher; 9 import org.hamcrest.Description; 10 import org.hamcrest.Matcher; 11 import org.mockito.internal.util.Decamelizer; 12 13 /** 14 * Allows creating customized argument matchers. 15 * <p> 16 * ArgumentMatcher is an hamcrest {@link Matcher} with predefined describeTo() method. 17 * In case of failure, ArgumentMatcher generates description based on <b>decamelized class name</b> - to promote meaningful class names. 18 * For example <b>StringWithStrongLanguage</b> matcher will generate 'String with strong language' description. 19 * You can always override describeTo() method and provide detailed description. 20 * <p> 21 * Use {@link Matchers#argThat} method and pass an instance of hamcrest {@link Matcher}, e.g: 22 * 23 * <pre class="code"><code class="java"> 24 * class IsListOfTwoElements extends ArgumentMatcher<List> { 25 * public boolean matches(Object list) { 26 * return ((List) list).size() == 2; 27 * } 28 * } 29 * 30 * List mock = mock(List.class); 31 * 32 * when(mock.addAll(argThat(new IsListOfTwoElements()))).thenReturn(true); 33 * 34 * mock.addAll(Arrays.asList("one", "two")); 35 * 36 * verify(mock).addAll(argThat(new IsListOfTwoElements())); 37 * </code></pre> 38 * 39 * To keep it readable you may want to extract method, e.g: 40 * 41 * <pre class="code"><code class="java"> 42 * verify(mock).addAll(<b>argThat(new IsListOfTwoElements())</b>); 43 * //becomes 44 * verify(mock).addAll(<b>listOfTwoElements()</b>); 45 * </code></pre> 46 * 47 * <b>Warning:</b> Be reasonable with using complicated argument matching, especially custom argument matchers, as it can make the test less readable. 48 * Sometimes it's better to implement equals() for arguments that are passed to mocks 49 * (Mockito naturally uses equals() for argument matching). 50 * This can make the test cleaner. 51 * <p> 52 * Also, <b>sometimes {@link ArgumentCaptor} may be a better fit</b> than custom matcher. 53 * For example, if custom argument matcher is not likely to be reused 54 * or you just need it to assert on argument values to complete verification of behavior. 55 * <p> 56 * Read more about other matchers in javadoc for {@link Matchers} class 57 * 58 * @param <T> type of argument 59 */ 60 public abstract class ArgumentMatcher<T> extends BaseMatcher<T> { 61 62 private static final long serialVersionUID = -2145234737829370369L; 63 64 /** 65 * Returns whether this matcher accepts the given argument. 66 * <p> 67 * The method should <b>never</b> assert if the argument doesn't match. It 68 * should only return false. 69 * 70 * @param argument 71 * the argument 72 * @return whether this matcher accepts the given argument. 73 */ matches(Object argument)74 public abstract boolean matches(Object argument); 75 76 /** 77 * By default this method decamelizes matchers name to promote meaningful names for matchers. 78 * <p> 79 * For example <b>StringWithStrongLanguage</b> matcher will generate 'String with strong language' description in case of failure. 80 * <p> 81 * You might want to override this method to 82 * provide more specific description of the matcher (useful when 83 * verification failures are reported). 84 * 85 * @param description the description to which the matcher description is 86 * appended. 87 */ describeTo(Description description)88 public void describeTo(Description description) { 89 String className = getClass().getSimpleName(); 90 description.appendText(Decamelizer.decamelizeMatcher(className)); 91 } 92 }