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 java.util.Collection;
8import org.mockito.internal.stubbing.answers.ReturnsArgumentAt;
9import org.mockito.internal.stubbing.answers.ReturnsElementsOf;
10import org.mockito.internal.stubbing.defaultanswers.ForwardsInvocations;
11import org.mockito.stubbing.Answer;
12import org.mockito.stubbing.Answer1;
13import org.mockito.stubbing.Answer2;
14import org.mockito.stubbing.Answer3;
15import org.mockito.stubbing.Answer4;
16import org.mockito.stubbing.Answer5;
17import org.mockito.stubbing.VoidAnswer1;
18import org.mockito.stubbing.VoidAnswer2;
19import org.mockito.stubbing.VoidAnswer3;
20import org.mockito.stubbing.VoidAnswer4;
21import org.mockito.stubbing.VoidAnswer5;
22
23import static org.mockito.internal.stubbing.answers.AnswerFunctionalInterfaces.toAnswer;
24
25/**
26 * Additional answers provides factory methods for answers.
27 *
28 * <p>Currently offer answers that can return the parameter of an invocation at a certain position,
29 * along with answers that draw on a strongly typed interface to provide a neater way to write custom answers
30 * that either return a value or are void (see answer interfaces in {@link org.mockito.stubbing}).
31 *
32 * <p>See factory methods for more information : {@link #returnsFirstArg}, {@link #returnsSecondArg},
33 * {@link #returnsLastArg}, {@link #returnsArgAt}, {@link #answer} and {@link #answerVoid}
34 *
35 * @since 1.9.5
36 */
37@SuppressWarnings("unchecked")
38public class AdditionalAnswers {
39    /**
40     * Returns the first parameter of an invocation.
41     *
42     * <p>
43     *     This additional answer could be used at stub time using the
44     *     <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
45     *
46     * <pre class="code"><code class="java">
47     * given(carKeyFob.authenticate(carKey)).will(returnsFirstArg());
48     * doAnswer(returnsFirstArg()).when(carKeyFob).authenticate(carKey);
49     * </code></pre>
50     * </p>
51     *
52     * <p>
53     * This methods works with varargs as well, mockito will expand the vararg to return the argument
54     * at the given position. Suppose the following signature :
55     *
56     * <pre class="code"><code class="java">
57     * interface Person {
58     *     Dream remember(Dream... dreams);
59     * }
60     *
61     * // returns dream1
62     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsFirstArg());
63     * </code></pre>
64     *
65     * Mockito will return the vararg array if the first argument is a vararg in the method
66     * and if the return type has the same type as the vararg array.
67     *
68     * <pre class="code"><code class="java">
69     * interface Person {
70     *     Dream[] remember(Dream... otherDreams);
71     * }
72     *
73     * // returns otherDreams (happens to be a 4 elements array)
74     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsFirstArg());
75     * </code></pre>
76     * </p>
77     *
78     * @param <T> Return type of the invocation.
79     * @return Answer that will return the first argument of the invocation.
80     *
81     * @since 1.9.5
82     */
83    public static <T> Answer<T> returnsFirstArg() {
84        return (Answer<T>) new ReturnsArgumentAt(0);
85    }
86
87    /**
88     * Returns the second parameter of an invocation.
89     *
90     * <p>
91     *     This additional answer could be used at stub time using the
92     *     <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
93     *
94     * <pre class="code"><code class="java">
95     * given(trader.apply(leesFormula, onCreditDefaultSwap)).will(returnsSecondArg());
96     * doAnswer(returnsSecondArg()).when(trader).apply(leesFormula, onCreditDefaultSwap);
97     * </code></pre>
98     * </p>
99     *
100     * <p>
101     * This methods works with varargs as well, mockito will expand the vararg to return the argument
102     * at the given position. Suppose the following signature :
103     *
104     * <pre class="code"><code class="java">
105     * interface Person {
106     *     Dream remember(Dream dream, Dream... otherDreams);
107     * }
108     *
109     * // returns dream2
110     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsSecondArg());
111     * </code></pre>
112     *
113     * Mockito will return the vararg array if the second argument is a vararg in the method
114     * and if the return type has the same type as the vararg array.
115     *
116     * <pre class="code"><code class="java">
117     * interface Person {
118     *     Dream[] remember(Dream dream1, Dream... otherDreams);
119     * }
120     *
121     * // returns otherDreams (happens to be a 3 elements array)
122     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsSecondArg());
123     * </code></pre>
124     * </p>
125     *
126     * @param <T> Return type of the invocation.
127     * @return Answer that will return the second argument of the invocation.
128     *
129     * @since 1.9.5
130     */
131    public static <T> Answer<T> returnsSecondArg() {
132        return (Answer<T>) new ReturnsArgumentAt(1);
133    }
134
135    /**
136     * Returns the last parameter of an invocation.
137     *
138     * <p>
139     *     This additional answer could be used at stub time using the
140     *     <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
141     *
142     * <pre class="code"><code class="java">
143     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsLastArg());
144     * doAnswer(returnsLastArg()).when(person).remember(dream1, dream2, dream3, dream4);
145     * </code></pre>
146     * </p>
147     *
148     * <p>
149     * This methods works with varargs as well, mockito will expand the vararg to return the argument
150     * at the given position. Suppose the following signature :
151     *
152     * <pre class="code"><code class="java">
153     * interface Person {
154     *     Dream remember(Dream dream, Dream... otherDreams);
155     * }
156     *
157     * // returns dream4
158     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsLastArg());
159     * </code></pre>
160     *
161     * Mockito will return the vararg array if the given {@code position} targets the vararg index in the method
162     * and if the return type has the same type as the vararg array.
163     *
164     * <pre class="code"><code class="java">
165     * interface Person {
166     *     Dream[] remember(Dream dream1, Dream dream2, Dream dream3, Dream... otherDreams);
167     * }
168     *
169     * // returns otherDreams (happens to be a single element array)
170     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsLastArg());
171     * </code></pre>
172     * </p>
173     *
174     * @param <T> Return type of the invocation.
175     * @return Answer that will return the last argument of the invocation.
176     *
177     * @since 1.9.5
178     */
179    public static <T> Answer<T> returnsLastArg() {
180        return (Answer<T>) new ReturnsArgumentAt(ReturnsArgumentAt.LAST_ARGUMENT);
181    }
182
183    /**
184     * Returns the parameter of an invocation at the given position.
185     *
186     * <p>
187     * This additional answer could be used at stub time using the
188     * <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
189     *
190     * <pre class="code"><code class="java">
191     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsArgAt(3));
192     * doAnswer(returnsArgAt(3)).when(person).remember(dream1, dream2, dream3, dream4);
193     * </code></pre>
194     * </p>
195     *
196     * <p>
197     * This methods works with varargs as well, mockito will expand the vararg to return the argument
198     * at the given position. Suppose the following signature :
199     *
200     * <pre class="code"><code class="java">
201     * interface Person {
202     *     Dream remember(Dream dream, Dream... otherDreams);
203     * }
204     *
205     * // returns dream 3
206     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsArgAt(2));
207     * </code></pre>
208     *
209     * Mockito will return the vararg array if the given {@code position} targets the vararg index in the method
210     * and if the return type has the same type as the vararg array.
211     *
212     * <pre class="code"><code class="java">
213     * interface Person {
214     *     Dream[] remember(Dream dream, Dream... otherDreams);
215     * }
216     *
217     * // returns otherDreams array (contains dream2, dream,3, dream4)
218     * given(person.remember(dream1, dream2, dream3, dream4)).will(returnsArgAt(1));
219     * </code></pre>
220     * </p>
221     *
222     * @param <T> Return type of the invocation.
223     * @param position index of the argument from the list of arguments.
224     * @return Answer that will return the argument from the given position in the argument's list
225     *
226     * @since 1.9.5
227     */
228    public static <T> Answer<T> returnsArgAt(int position) {
229        return (Answer<T>) new ReturnsArgumentAt(position);
230    }
231
232    /**
233     * An answer that directly forwards the calls to the delegate. The delegate may or may not be of the same type as the mock.
234     * If the type is different, a matching method needs to be found on delegate type otherwise an exception is thrown.
235     * <p>
236     * Useful for spies or partial mocks of objects that are difficult to mock
237     * or spy using the usual spy API. Possible use cases:
238     * <ul>
239     *     <li>Final classes but with an interface</li>
240     *     <li>Already custom proxied object</li>
241     *     <li>Special objects with a finalize method, i.e. to avoid executing it 2 times</li>
242     * </ul>
243     *
244     * <p>
245     * The difference with the regular spy:
246     * <ul>
247     *   <li>
248     *     The regular spy ({@link Mockito#spy(Object)}) contains <strong>all</strong> state from the spied instance
249     *     and the methods are invoked on the spy. The spied instance is only used at mock creation to copy the state from.
250     *     If you call a method on a regular spy and it internally calls other methods on this spy, those calls are remembered
251     *     for verifications, and they can be effectively stubbed.
252     *   </li>
253     *   <li>
254     *     The mock that delegates simply delegates all methods to the delegate.
255     *     The delegate is used all the time as methods are delegated onto it.
256     *     If you call a method on a mock that delegates and it internally calls other methods on this mock,
257     *     those calls are <strong>not</strong> remembered for verifications, stubbing does not have effect on them, too.
258     *     Mock that delegates is less powerful than the regular spy but it is useful when the regular spy cannot be created.
259     *   </li>
260     * </ul>
261     * An example with a final class that we want to delegate to:
262     * <p>
263     * <pre class="code"><code class="java">
264     *   final class DontYouDareToMockMe implements list { ... }
265     *
266     *   DontYouDareToMockMe awesomeList = new DontYouDareToMockMe();
267     *
268     *   List mock = mock(List.class, delegatesTo(awesomeList));
269     * </code></pre>
270     *
271     * <p>
272     * This feature suffers from the same drawback as the spy.
273     * The mock will call the delegate if you use regular when().then() stubbing style.
274     * Since the real implementation is called this might have some side effects.
275     * Therefore you should to use the doReturn|Throw|Answer|CallRealMethod stubbing style. Example:
276     *
277     * <pre class="code"><code class="java">
278     *   List listWithDelegate = mock(List.class, AdditionalAnswers.delegatesTo(awesomeList));
279     *
280     *   //Impossible: real method is called so listWithDelegate.get(0) throws IndexOutOfBoundsException (the list is yet empty)
281     *   when(listWithDelegate.get(0)).thenReturn("foo");
282     *
283     *   //You have to use doReturn() for stubbing
284     *   doReturn("foo").when(listWithDelegate).get(0);
285     * </code></pre>
286     *
287     * @param delegate The delegate to forward calls to. It does not have to be of the same type as the mock (although it usually is).
288     *                 The only requirement is that the instance should have compatible method signatures including the return values.
289     *                 Only the methods that were actually executed on the mock need to be present on the delegate type.
290     * @return the answer
291     *
292     * @since 1.9.5
293     */
294    public static <T> Answer<T> delegatesTo(Object delegate) {
295        return (Answer<T>) new ForwardsInvocations(delegate);
296    }
297
298    /**
299     * Returns elements of the collection. Keeps returning the last element forever.
300     * Might be useful on occasion when you have a collection of elements to return.
301     * <p>
302     * <pre class="code"><code class="java">
303     *   //this:
304     *   when(mock.foo()).thenReturn(1, 2, 3);
305     *
306     *   //is equivalent to:
307     *   when(mock.foo()).thenAnswer(new ReturnsElementsOf(Arrays.asList(1, 2, 3)));
308     * </code></pre>
309     *
310     * @param elements The collection of elements to return.
311     * @return the answer
312     *
313     * @since 1.9.5
314     */
315    public static <T> Answer<T> returnsElementsOf(Collection<?> elements) {
316        return (Answer<T>) new ReturnsElementsOf(elements);
317    }
318
319    /**
320     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
321     * ideally in Java 8
322     * @param answer interface to the answer - which is expected to return something
323     * @param <T> return type
324     * @param <A> input parameter type 1
325     * @return the answer object to use
326     * @since 2.1.0
327     */
328    @Incubating
329    public static <T, A> Answer<T> answer(Answer1<T, A> answer) {
330        return toAnswer(answer);
331    }
332
333    /**
334     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
335     * ideally in Java 8
336     * @param answer interface to the answer - a void method
337     * @param <A> input parameter type 1
338     * @return the answer object to use
339     * @since 2.1.0
340     */
341    @Incubating
342    public static <A> Answer<Void> answerVoid(VoidAnswer1<A> answer) {
343        return toAnswer(answer);
344    }
345
346    /**
347     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
348     * ideally in Java 8
349     * @param answer interface to the answer - which is expected to return something
350     * @param <T> return type
351     * @param <A> input parameter type 1
352     * @param <B> input parameter type 2
353     * @return the answer object to use
354     * @since 2.1.0
355     */
356    @Incubating
357    public static <T, A, B> Answer<T> answer(Answer2<T, A, B> answer) {
358        return toAnswer(answer);
359    }
360
361    /**
362     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
363     * ideally in Java 8
364     * @param answer interface to the answer - a void method
365     * @param <A> input parameter type 1
366     * @param <B> input parameter type 2
367     * @return the answer object to use
368     * @since 2.1.0
369     */
370    @Incubating
371    public static <A, B> Answer<Void> answerVoid(VoidAnswer2<A, B> answer) {
372        return toAnswer(answer);
373    }
374
375    /**
376     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
377     * ideally in Java 8
378     * @param answer interface to the answer - which is expected to return something
379     * @param <T> return type
380     * @param <A> input parameter type 1
381     * @param <B> input parameter type 2
382     * @param <C> input parameter type 3
383     * @return the answer object to use
384     * @since 2.1.0
385     */
386    @Incubating
387    public static <T, A, B, C> Answer<T> answer(Answer3<T, A, B, C> answer) {
388        return toAnswer(answer);
389    }
390
391    /**
392     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
393     * ideally in Java 8
394     * @param answer interface to the answer - a void method
395     * @param <A> input parameter type 1
396     * @param <B> input parameter type 2
397     * @param <C> input parameter type 3
398     * @return the answer object to use
399     * @since 2.1.0
400     */
401    @Incubating
402    public static <A, B, C> Answer<Void> answerVoid(VoidAnswer3<A, B, C> answer) {
403        return toAnswer(answer);
404    }
405
406    /**
407     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
408     * ideally in Java 8
409     * @param answer interface to the answer - which is expected to return something
410     * @param <T> return type
411     * @param <A> input parameter type 1
412     * @param <B> input parameter type 2
413     * @param <C> input parameter type 3
414     * @param <D> input parameter type 4
415     * @return the answer object to use
416     * @since 2.1.0
417     */
418    @Incubating
419    public static <T, A, B, C, D> Answer<T> answer(Answer4<T, A, B, C, D> answer) {
420        return toAnswer(answer);
421    }
422
423    /**
424     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
425     * ideally in Java 8
426     * @param answer interface to the answer - a void method
427     * @param <A> input parameter type 1
428     * @param <B> input parameter type 2
429     * @param <C> input parameter type 3
430     * @param <D> input parameter type 4
431     * @return the answer object to use
432     * @since 2.1.0
433     */
434    @Incubating
435    public static <A, B, C, D> Answer<Void> answerVoid(VoidAnswer4<A, B, C, D> answer) {
436        return toAnswer(answer);
437    }
438
439    /**
440     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
441     * ideally in Java 8
442     * @param answer interface to the answer - which is expected to return something
443     * @param <T> return type
444     * @param <A> input parameter type 1
445     * @param <B> input parameter type 2
446     * @param <C> input parameter type 3
447     * @param <D> input parameter type 4
448     * @param <E> input parameter type 5
449     * @return the answer object to use
450     * @since 2.1.0
451     */
452    @Incubating
453    public static <T, A, B, C, D, E> Answer<T> answer(Answer5<T, A, B, C, D, E> answer) {
454        return toAnswer(answer);
455    }
456
457    /**
458     * Creates an answer from a functional interface - allows for a strongly typed answer to be created
459     * ideally in Java 8
460     *
461     * @param answer interface to the answer - a void method
462     * @param <A> input parameter type 1
463     * @param <B> input parameter type 2
464     * @param <C> input parameter type 3
465     * @param <D> input parameter type 4
466     * @param <E> input parameter type 5
467     * @return the answer object to use
468     * @since 2.1.0
469     */
470    @Incubating
471    public static <A, B, C, D, E> Answer<Void> answerVoid(VoidAnswer5<A, B, C, D, E> answer) {
472        return toAnswer(answer);
473    }
474}
475