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&lt;Person&gt; 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&lt;Person&gt; 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: &#64;{@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&lt;Person&gt; peopleCaptor = ArgumentCaptor.forClass(Person.class);
110     *   verify(mock, times(2)).doSomething(peopleCaptor.capture());
111     *
112     *   List&lt;Person&gt; 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&lt;Person&gt; 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