1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito; 6 7 import org.mockito.internal.matchers.CapturingMatcher; 8 import org.mockito.internal.matchers.VarargCapturingMatcher; 9 import org.mockito.internal.progress.HandyReturnValues; 10 11 import java.util.List; 12 13 /** 14 * Use it to capture argument values for further assertions. 15 * 16 * <p> 17 * Mockito verifies argument values in natural java style: by using an equals() method. 18 * This is also the recommended way of matching arguments because it makes tests clean & simple. 19 * In some situations though, it is helpful to assert on certain arguments after the actual verification. 20 * For example: 21 * <pre class="code"><code class="java"> 22 * ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class); 23 * verify(mock).doSomething(argument.capture()); 24 * assertEquals("John", argument.getValue().getName()); 25 * </code></pre> 26 * 27 * <p> 28 * <strong>Warning:</strong> it is recommended to use ArgumentCaptor with verification <strong>but not</strong> with stubbing. 29 * Using ArgumentCaptor with stubbing may decrease test readability because captor is created outside of assert (aka verify or 'then') block. 30 * Also it may reduce defect localization because if stubbed method was not called then no argument is captured. 31 * 32 * <p> 33 * In a way ArgumentCaptor is related to custom argument matchers (see javadoc for {@link ArgumentMatcher} class). 34 * Both techniques can be used for making sure certain arguments where passed to mocks. 35 * However, ArgumentCaptor may be a better fit if: 36 * <ul> 37 * <li>custom argument matcher is not likely to be reused</li> 38 * <li>you just need it to assert on argument values to complete verification</li> 39 * </ul> 40 * Custom argument matchers via {@link ArgumentMatcher} are usually better for stubbing. 41 * 42 * <p> 43 * This utility class <strong>*don't do any type checks*</strong>, the generic signatures are only there to avoid casting 44 * in your code. If you want specific types, then you should do that the captured values. 45 * This behavior might change (type checks could be added) in a 46 * future major release. 47 * <p> 48 * There is an <strong>annotation</strong> that you might find useful: @{@link Captor} 49 * <p> 50 * See the full documentation on Mockito in javadoc for {@link Mockito} class. 51 * 52 * @see Captor 53 * @since 1.8.0 54 */ 55 public class ArgumentCaptor<T> { 56 57 HandyReturnValues handyReturnValues = new HandyReturnValues(); 58 59 private final CapturingMatcher<T> capturingMatcher = new CapturingMatcher<T>(); 60 private final VarargCapturingMatcher<T> varargCapturingMatcher = new VarargCapturingMatcher<T>(); 61 private final Class<T> clazz; 62 63 /** 64 * @deprecated 65 * 66 * <b>Please use factory method {@link ArgumentCaptor#forClass(Class)} to create captors</b> 67 * <p> 68 * This is required to avoid NullPointerExceptions when autoUnboxing primitive types. 69 * See issue 99. 70 * <p> 71 * Example: 72 * <pre class="code"><code class="java"> 73 * ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class); 74 * verify(mock).doSomething(argument.capture()); 75 * assertEquals("John", argument.getValue().getName()); 76 * </code></pre> 77 */ 78 @Deprecated 79 public ArgumentCaptor() { 80 this.clazz = null; 81 } 82 83 ArgumentCaptor(Class<T> clazz) { 84 this.clazz = clazz; 85 } 86 87 /** 88 * Use it to capture the argument. This method <b>must be used inside of verification</b>. 89 * <p> 90 * Internally, this method registers a special implementation of an {@link ArgumentMatcher}. 91 * This argument matcher stores the argument value so that you can use it later to perform assertions. 92 * <p> 93 * See examples in javadoc for {@link ArgumentCaptor} class. 94 * 95 * @return null or default values 96 */ 97 public T capture() { 98 Mockito.argThat(capturingMatcher); 99 return handyReturnValues.returnFor(clazz); 100 } 101 102 /** 103 * Use it to capture the variable arguments. This method <b>must be used inside of verification</b>. 104 * <p> 105 * Internally, this method registers a special implementation of an {@link ArgumentMatcher}. 106 * This argument matcher stores the variable arguments values so that you can use it later to perform assertions. 107 * <p> 108 * See examples in javadoc for {@link ArgumentCaptor} class. 109 * 110 * @return null or default values 111 */ 112 public T captureVararg() { 113 Mockito.argThat(varargCapturingMatcher); 114 return handyReturnValues.returnFor(clazz); 115 } 116 117 118 /** 119 * Returns the captured value of the argument. 120 * <p> 121 * If the method was called multiple times then it returns the latest captured value. 122 * <p> 123 * See examples in javadoc for {@link ArgumentCaptor} class. 124 * 125 * @return captured argument value 126 */ 127 public T getValue() { 128 return this.capturingMatcher.getLastValue(); 129 } 130 131 /** 132 * Returns the captured value of the variable arguments. 133 * <p> 134 * If the method was called multiple times then it returns the latest captured variable arguments. 135 * <p> 136 * See examples in javadoc for {@link ArgumentCaptor} class. 137 * 138 * @return captured varargs 139 */ 140 public List<T> getVarargsValues() { 141 return this.varargCapturingMatcher.getLastVarargs(); 142 } 143 144 /** 145 * Returns all captured values. Use it in case the verified method was called multiple times. 146 * <p> 147 * Example: 148 * <pre class="code"><code class="java"> 149 * ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class); 150 * verify(mock, times(2)).doSomething(peopleCaptor.capture()); 151 * 152 * List<Person> capturedPeople = peopleCaptor.getAllValues(); 153 * assertEquals("John", capturedPeople.get(0).getName()); 154 * assertEquals("Jane", capturedPeople.get(1).getName()); 155 * </code></pre> 156 * See more examples in javadoc for {@link ArgumentCaptor} class. 157 * 158 * @return captured argument value 159 */ 160 public List<T> getAllValues() { 161 return this.capturingMatcher.getAllValues(); 162 } 163 164 /** 165 * Returns all captured variable arguments. Use it in case the verified method was called multiple times. 166 * <p> 167 * Example: 168 * <pre class="code"><code class="java"> 169 * ArgumentCaptor<Person> peopleFornamesCaptor = ArgumentCaptor.forClass(String.class); 170 * verify(mock, times(2)).doSomething(peopleFornamesCaptor.captureVarargs()); 171 * 172 * List<String> peopleFornames = peopleFornamesCaptor.getAllVarargs(); 173 * assertThat(peopleFornames.get(0)).contains("John", "Carl"); 174 * assertThat(peopleFornames.get(1)).contains("Janes", "Eloise", "Lois"); 175 * </code></pre> 176 * See more examples in javadoc for {@link ArgumentCaptor} class. 177 * 178 * @return all captured varargs 179 */ 180 public List<List<T>> getAllVarargsValues() { 181 return this.varargCapturingMatcher.getAllVarargs(); 182 } 183 184 /** 185 * Build a new <code>ArgumentCaptor</code>. 186 * <p> 187 * Note that an <code>ArgumentCaptor</code> <b>*don't do any type checks*</b>, it is only there to avoid casting 188 * in your code. This might however change (type checks could be added) in a 189 * future major release. 190 * 191 * @param clazz Type matching the parameter to be captured. 192 * @param <T> Type of clazz 193 * @return A new ArgumentCaptor 194 */ 195 public static <T> ArgumentCaptor<T> forClass(Class<T> clazz) { 196 return new ArgumentCaptor<T>(clazz); 197 } 198 }