1/* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5package org.mockito; 6 7import static org.mockito.internal.util.Primitives.defaultValue; 8 9import java.util.List; 10 11import org.mockito.internal.matchers.CapturingMatcher; 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 * Example of capturing varargs: 28 * <pre class="code"><code class="java"> 29 * //capturing varargs: 30 * ArgumentCaptor<Person> varArgs = ArgumentCaptor.forClass(Person.class); 31 * verify(mock).varArgMethod(varArgs.capture()); 32 * List expected = asList(new Person("John"), new Person("Jane")); 33 * assertEquals(expected, varArgs.getAllValues()); 34 * </code></pre> 35 * 36 * <p> 37 * <strong>Warning:</strong> it is recommended to use ArgumentCaptor with verification <strong>but not</strong> with stubbing. 38 * Using ArgumentCaptor with stubbing may decrease test readability because captor is created outside of assert (aka verify or 'then') block. 39 * Also it may reduce defect localization because if stubbed method was not called then no argument is captured. 40 * 41 * <p> 42 * In a way ArgumentCaptor is related to custom argument matchers (see javadoc for {@link ArgumentMatcher} class). 43 * Both techniques can be used for making sure certain arguments where passed to mocks. 44 * However, ArgumentCaptor may be a better fit if: 45 * <ul> 46 * <li>custom argument matcher is not likely to be reused</li> 47 * <li>you just need it to assert on argument values to complete verification</li> 48 * </ul> 49 * Custom argument matchers via {@link ArgumentMatcher} are usually better for stubbing. 50 * 51 * <p> 52 * This utility class <strong>*don't do any type checks*</strong>, the generic signatures are only there to avoid casting 53 * in your code. 54 * <p> 55 * There is an <strong>annotation</strong> that you might find useful: @{@link Captor} 56 * <p> 57 * See the full documentation on Mockito in javadoc for {@link Mockito} class. 58 * 59 * @see Captor 60 * @since 1.8.0 61 */ 62public class ArgumentCaptor<T> { 63 64 65 private final CapturingMatcher<T> capturingMatcher = new CapturingMatcher<T>(); 66 private final Class<? extends T> clazz; 67 68 private ArgumentCaptor(Class<? extends T> clazz) { 69 this.clazz = clazz; 70 } 71 72 /** 73 * Use it to capture the argument. This method <b>must be used inside of verification</b>. 74 * <p> 75 * Internally, this method registers a special implementation of an {@link ArgumentMatcher}. 76 * This argument matcher stores the argument value so that you can use it later to perform assertions. 77 * <p> 78 * See examples in javadoc for {@link ArgumentCaptor} class. 79 * 80 * @return null or default values 81 */ 82 public T capture() { 83 Mockito.argThat(capturingMatcher); 84 return defaultValue(clazz); 85 } 86 87 /** 88 * Returns the captured value of the argument. When capturing varargs use {@link #getAllValues()}. 89 * <p> 90 * If verified method was called multiple times then this method it returns the latest captured value. 91 * <p> 92 * See examples in javadoc for {@link ArgumentCaptor} class. 93 * 94 * @return captured argument value 95 */ 96 public T getValue() { 97 return this.capturingMatcher.getLastValue(); 98 } 99 100 /** 101 * Returns all captured values. Use it when capturing varargs or when the verified method was called multiple times. 102 * When varargs method was called multiple times, this method returns merged list of all values from all invocations. 103 * <p> 104 * Example: 105 * <pre class="code"><code class="java"> 106 * mock.doSomething(new Person("John"); 107 * mock.doSomething(new Person("Jane"); 108 * 109 * ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class); 110 * verify(mock, times(2)).doSomething(peopleCaptor.capture()); 111 * 112 * List<Person> capturedPeople = peopleCaptor.getAllValues(); 113 * assertEquals("John", capturedPeople.get(0).getName()); 114 * assertEquals("Jane", capturedPeople.get(1).getName()); 115 * </pre> 116 * 117 * Example of capturing varargs: 118 * <pre class="code"><code class="java"> 119 * mock.countPeople(new Person("John"), new Person("Jane"); //vararg method 120 * 121 * ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class); 122 * 123 * verify(mock).countPeople(peopleCaptor.capture()); 124 * 125 * List expected = asList(new Person("John"), new Person("Jane")); 126 * assertEquals(expected, peopleCaptor.getAllValues()); 127 * </code></pre> 128 * See more examples in javadoc for {@link ArgumentCaptor} class. 129 * 130 * @return captured argument value 131 */ 132 public List<T> getAllValues() { 133 return this.capturingMatcher.getAllValues(); 134 } 135 136 /** 137 * Build a new <code>ArgumentCaptor</code>. 138 * <p> 139 * Note that an <code>ArgumentCaptor</code> <b>*don't do any type checks*</b>, it is only there to avoid casting 140 * in your code. This might however change (type checks could be added) in a 141 * future major release. 142 * 143 * @param clazz Type matching the parameter to be captured. 144 * @param <S> Type of clazz 145 * @param <U> Type of object captured by the newly built ArgumentCaptor 146 * @return A new ArgumentCaptor 147 */ 148 public static <U,S extends U> ArgumentCaptor<U> forClass(Class<S> clazz) { 149 return new ArgumentCaptor<U>(clazz); 150 } 151} 152