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 java.util.Collection;
8 import org.mockito.internal.stubbing.answers.ReturnsArgumentAt;
9 import org.mockito.internal.stubbing.answers.ReturnsElementsOf;
10 import org.mockito.internal.stubbing.defaultanswers.ForwardsInvocations;
11 import org.mockito.stubbing.Answer;
12 import org.mockito.stubbing.Answer1;
13 import org.mockito.stubbing.Answer2;
14 import org.mockito.stubbing.Answer3;
15 import org.mockito.stubbing.Answer4;
16 import org.mockito.stubbing.Answer5;
17 import org.mockito.stubbing.VoidAnswer1;
18 import org.mockito.stubbing.VoidAnswer2;
19 import org.mockito.stubbing.VoidAnswer3;
20 import org.mockito.stubbing.VoidAnswer4;
21 import org.mockito.stubbing.VoidAnswer5;
22 
23 import 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")
38 public 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      */
returnsFirstArg()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      */
returnsSecondArg()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      */
returnsLastArg()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      */
returnsArgAt(int position)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      */
delegatesTo(Object delegate)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      */
returnsElementsOf(Collection<?> elements)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
answer(Answer1<T, A> answer)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
answerVoid(VoidAnswer1<A> answer)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
answer(Answer2<T, A, B> answer)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
answerVoid(VoidAnswer2<A, B> answer)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
answer(Answer3<T, A, B, C> answer)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
answerVoid(VoidAnswer3<A, B, C> answer)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
answer(Answer4<T, A, B, C, D> answer)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
answerVoid(VoidAnswer4<A, B, C, D> answer)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
answer(Answer5<T, A, B, C, D, E> answer)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
answerVoid(VoidAnswer5<A, B, C, D, E> answer)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