| /* |
| * Copyright (c) 2007 Mockito contributors |
| * This program is made available under the terms of the MIT License. |
| */ |
| package org.mockito; |
| |
| import static org.mockito.internal.util.Primitives.defaultValue; |
| |
| import java.util.List; |
| |
| import org.mockito.internal.matchers.CapturingMatcher; |
| |
| /** |
| * Use it to capture argument values for further assertions. |
| * |
| * <p> |
| * Mockito verifies argument values in natural java style: by using an equals() method. |
| * This is also the recommended way of matching arguments because it makes tests clean & simple. |
| * In some situations though, it is helpful to assert on certain arguments after the actual verification. |
| * For example: |
| * <pre class="code"><code class="java"> |
| * ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class); |
| * verify(mock).doSomething(argument.capture()); |
| * assertEquals("John", argument.getValue().getName()); |
| * </code></pre> |
| * |
| * Example of capturing varargs: |
| * <pre class="code"><code class="java"> |
| * //capturing varargs: |
| * ArgumentCaptor<Person> varArgs = ArgumentCaptor.forClass(Person.class); |
| * verify(mock).varArgMethod(varArgs.capture()); |
| * List expected = asList(new Person("John"), new Person("Jane")); |
| * assertEquals(expected, varArgs.getAllValues()); |
| * </code></pre> |
| * |
| * <p> |
| * <strong>Warning:</strong> it is recommended to use ArgumentCaptor with verification <strong>but not</strong> with stubbing. |
| * Using ArgumentCaptor with stubbing may decrease test readability because captor is created outside of assert (aka verify or 'then') block. |
| * Also it may reduce defect localization because if stubbed method was not called then no argument is captured. |
| * |
| * <p> |
| * In a way ArgumentCaptor is related to custom argument matchers (see javadoc for {@link ArgumentMatcher} class). |
| * Both techniques can be used for making sure certain arguments where passed to mocks. |
| * However, ArgumentCaptor may be a better fit if: |
| * <ul> |
| * <li>custom argument matcher is not likely to be reused</li> |
| * <li>you just need it to assert on argument values to complete verification</li> |
| * </ul> |
| * Custom argument matchers via {@link ArgumentMatcher} are usually better for stubbing. |
| * |
| * <p> |
| * This utility class <strong>*don't do any type checks*</strong>, the generic signatures are only there to avoid casting |
| * in your code. |
| * <p> |
| * There is an <strong>annotation</strong> that you might find useful: @{@link Captor} |
| * <p> |
| * See the full documentation on Mockito in javadoc for {@link Mockito} class. |
| * |
| * @see Captor |
| * @since 1.8.0 |
| */ |
| public class ArgumentCaptor<T> { |
| |
| |
| private final CapturingMatcher<T> capturingMatcher = new CapturingMatcher<T>(); |
| private final Class<? extends T> clazz; |
| |
| private ArgumentCaptor(Class<? extends T> clazz) { |
| this.clazz = clazz; |
| } |
| |
| /** |
| * Use it to capture the argument. This method <b>must be used inside of verification</b>. |
| * <p> |
| * Internally, this method registers a special implementation of an {@link ArgumentMatcher}. |
| * This argument matcher stores the argument value so that you can use it later to perform assertions. |
| * <p> |
| * See examples in javadoc for {@link ArgumentCaptor} class. |
| * |
| * @return null or default values |
| */ |
| public T capture() { |
| Mockito.argThat(capturingMatcher); |
| return defaultValue(clazz); |
| } |
| |
| /** |
| * Returns the captured value of the argument. When capturing varargs use {@link #getAllValues()}. |
| * <p> |
| * If verified method was called multiple times then this method it returns the latest captured value. |
| * <p> |
| * See examples in javadoc for {@link ArgumentCaptor} class. |
| * |
| * @return captured argument value |
| */ |
| public T getValue() { |
| return this.capturingMatcher.getLastValue(); |
| } |
| |
| /** |
| * Returns all captured values. Use it when capturing varargs or when the verified method was called multiple times. |
| * When varargs method was called multiple times, this method returns merged list of all values from all invocations. |
| * <p> |
| * Example: |
| * <pre class="code"><code class="java"> |
| * mock.doSomething(new Person("John"); |
| * mock.doSomething(new Person("Jane"); |
| * |
| * ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class); |
| * verify(mock, times(2)).doSomething(peopleCaptor.capture()); |
| * |
| * List<Person> capturedPeople = peopleCaptor.getAllValues(); |
| * assertEquals("John", capturedPeople.get(0).getName()); |
| * assertEquals("Jane", capturedPeople.get(1).getName()); |
| * </pre> |
| * |
| * Example of capturing varargs: |
| * <pre class="code"><code class="java"> |
| * mock.countPeople(new Person("John"), new Person("Jane"); //vararg method |
| * |
| * ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class); |
| * |
| * verify(mock).countPeople(peopleCaptor.capture()); |
| * |
| * List expected = asList(new Person("John"), new Person("Jane")); |
| * assertEquals(expected, peopleCaptor.getAllValues()); |
| * </code></pre> |
| * See more examples in javadoc for {@link ArgumentCaptor} class. |
| * |
| * @return captured argument value |
| */ |
| public List<T> getAllValues() { |
| return this.capturingMatcher.getAllValues(); |
| } |
| |
| /** |
| * Build a new <code>ArgumentCaptor</code>. |
| * <p> |
| * Note that an <code>ArgumentCaptor</code> <b>*don't do any type checks*</b>, it is only there to avoid casting |
| * in your code. This might however change (type checks could be added) in a |
| * future major release. |
| * |
| * @param clazz Type matching the parameter to be captured. |
| * @param <S> Type of clazz |
| * @param <U> Type of object captured by the newly built ArgumentCaptor |
| * @return A new ArgumentCaptor |
| */ |
| public static <U,S extends U> ArgumentCaptor<U> forClass(Class<S> clazz) { |
| return new ArgumentCaptor<U>(clazz); |
| } |
| } |