Home | History | Annotate | Download | only in mockito
      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 org.mockito.internal.stubbing.answers.ReturnsArgumentAt;
      8 import org.mockito.internal.stubbing.answers.ReturnsElementsOf;
      9 import org.mockito.internal.stubbing.defaultanswers.ForwardsInvocations;
     10 import org.mockito.stubbing.Answer;
     11 
     12 import java.util.Collection;
     13 
     14 /**
     15  * Additional answers provides factory methods for less common answers.
     16  *
     17  * <p>Currently offer answers that can return the parameter of an invocation at a certain position.
     18  *
     19  * <p>See factory methods for more information : {@link #returnsFirstArg}, {@link #returnsSecondArg},
     20  * {@link #returnsLastArg} and {@link #returnsArgAt}
     21  *
     22  * @since 1.9.5
     23  */
     24 @SuppressWarnings("unchecked")
     25 public class AdditionalAnswers {
     26     private static final ReturnsArgumentAt RETURNS_FIRST_ARGUMENT = new ReturnsArgumentAt(0);
     27     private static final ReturnsArgumentAt RETURNS_SECOND_ARGUMENT = new ReturnsArgumentAt(1);
     28     private static final ReturnsArgumentAt RETURNS_LAST_ARGUMENT = new ReturnsArgumentAt(-1);
     29 
     30     /**
     31      * Returns the first parameter of an invocation.
     32      *
     33      * <p>
     34      *     This additional answer could be used at stub time using the
     35      *     <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
     36      * </p>
     37      *
     38      * <pre class="code"><code class="java">given(carKeyFob.authenticate(carKey)).will(returnsFirstArg());
     39      * doAnswer(returnsFirstArg()).when(carKeyFob).authenticate(carKey)</code></pre>
     40      *
     41      * @param <T> Return type of the invocation.
     42      * @return Answer that will return the first argument of the invocation.
     43      *
     44      * @since 1.9.5
     45      */
     46     public static <T> Answer<T> returnsFirstArg() {
     47         return (Answer<T>) RETURNS_FIRST_ARGUMENT;
     48     }
     49 
     50     /**
     51      * Returns the second parameter of an invocation.
     52      *
     53      * <p>
     54      *     This additional answer could be used at stub time using the
     55      *     <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
     56      * </p>
     57      *
     58      * <pre class="code"><code class="java">given(trader.apply(leesFormula, onCreditDefaultSwap)).will(returnsSecondArg());
     59      * doAnswer(returnsSecondArg()).when(trader).apply(leesFormula, onCreditDefaultSwap)</code></pre>
     60      *
     61      * @param <T> Return type of the invocation.
     62      * @return Answer that will return the second argument of the invocation.
     63      *
     64      * @since 1.9.5
     65      */
     66     public static <T> Answer<T> returnsSecondArg() {
     67         return (Answer<T>) RETURNS_SECOND_ARGUMENT;
     68     }
     69 
     70     /**
     71      * Returns the last parameter of an invocation.
     72      *
     73      * <p>
     74      *     This additional answer could be used at stub time using the
     75      *     <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
     76      * </p>
     77      *
     78      * <pre class="code"><code class="java">given(person.remember(dream1, dream2, dream3, dream4)).will(returnsLastArg());
     79      * doAnswer(returnsLastArg()).when(person).remember(dream1, dream2, dream3, dream4)</code></pre>
     80      *
     81      * @param <T> Return type of the invocation.
     82      * @return Answer that will return the last argument of the invocation.
     83      *
     84      * @since 1.9.5
     85      */
     86     public static <T> Answer<T> returnsLastArg() {
     87         return (Answer<T>) RETURNS_LAST_ARGUMENT;
     88     }
     89 
     90     /**
     91      * Returns the parameter of an invocation at the given position.
     92      *
     93      * <p>
     94      * This additional answer could be used at stub time using the
     95      * <code>then|do|will{@link org.mockito.stubbing.Answer}</code> methods. For example :
     96      * </p>
     97      *
     98      * <pre class="code"><code class="java">given(person.remember(dream1, dream2, dream3, dream4)).will(returnsArgAt(3));
     99      * doAnswer(returnsArgAt(3)).when(person).remember(dream1, dream2, dream3, dream4)</code></pre>
    100      *
    101      * @param <T> Return type of the invocation.
    102      * @return Answer that will return the second argument of the invocation.
    103      *
    104      * @since 1.9.5
    105      */
    106     public static <T> Answer<T> returnsArgAt(int position) {
    107         return (Answer<T>) new ReturnsArgumentAt(position);
    108     }
    109 
    110     /**
    111      * An answer that directly forwards the calls to the delegate.
    112      * <p>
    113      * Useful for spies or partial mocks of objects that are difficult to mock
    114      * or spy using the usual spy API. Possible use cases:
    115      * <ul>
    116      *     <li>Final classes but with an interface</li>
    117      *     <li>Already custom proxied object</li>
    118      *     <li>Special objects with a finalize method, i.e. to avoid executing it 2 times</li>
    119      * </ul>
    120      * For more details including the use cases reported by users take a look at
    121      * <a link="http://code.google.com/p/mockito/issues/detail?id=145">issue 145</a>.
    122      * <p>
    123      * The difference with the regular spy:
    124      * <ul>
    125      *   <li>
    126      *     The regular spy ({@link Mockito#spy(Object)}) contains <strong>all</strong> state from the spied instance
    127      *     and the methods are invoked on the spy. The spied instance is only used at mock creation to copy the state from.
    128      *     If you call a method on a regular spy and it internally calls other methods on this spy, those calls are remembered
    129      *     for verifications, and they can be effectively stubbed.
    130      *   </li>
    131      *   <li>
    132      *     The mock that delegates simply delegates all methods to the delegate.
    133      *     The delegate is used all the time as methods are delegated onto it.
    134      *     If you call a method on a mock that delegates and it internally calls other methods on this mock,
    135      *     those calls are <strong>not</strong> remembered for verifications, stubbing does not have effect on them, too.
    136      *     Mock that delegates is less powerful than the regular spy but it is useful when the regular spy cannot be created.
    137      *   </li>
    138      * </ul>
    139      * An example with a final class that we want to delegate to:
    140      * <p>
    141      * <pre class="code"><code class="java">
    142      *   final class DontYouDareToMockMe implements list { ... }
    143      *
    144      *   DontYouDareToMockMe awesomeList = new DontYouDareToMockMe();
    145      *
    146      *   List mock = mock(List.class, delegatesTo(awesomeList));
    147      * </code></pre>
    148      *
    149      * <p>
    150      * This feature suffers from the same drawback as the spy.
    151      * The mock will call the delegate if you use regular when().then() stubbing style.
    152      * Since the real implementation is called this might have some side effects.
    153      * Therefore you should to use the doReturn|Throw|Answer|CallRealMethod stubbing style. Example:
    154      *
    155      * <pre class="code"><code class="java">
    156      *   List listWithDelegate = mock(List.class, AdditionalAnswers.delegatesTo(awesomeList));
    157      *
    158      *   //Impossible: real method is called so listWithDelegate.get(0) throws IndexOutOfBoundsException (the list is yet empty)
    159      *   when(listWithDelegate.get(0)).thenReturn("foo");
    160      *
    161      *   //You have to use doReturn() for stubbing
    162      *   doReturn("foo").when(listWithDelegate).get(0);
    163      * </code></pre>
    164      *
    165      * @param delegate The delegate to forward calls to.
    166      * @return the answer
    167      *
    168      * @since 1.9.5
    169      */
    170     public static <T> Answer<T> delegatesTo(Object delegate) {
    171         return (Answer<T>) new ForwardsInvocations(delegate);
    172     }
    173 
    174     /**
    175      * Returns elements of the collection. Keeps returning the last element forever.
    176      * Might be useful on occasion when you have a collection of elements to return.
    177      * <p>
    178      * <pre class="code"><code class="java">
    179      *   //this:
    180      *   when(mock.foo()).thenReturn(1, 2, 3);
    181      *
    182      *   //is equivalent to:
    183      *   when(mock.foo()).thenAnswer(new ReturnsElementsOf(Arrays.asList(1, 2, 3)));
    184      * </code></pre>
    185      *
    186      * @param elements The collection of elements to return.
    187      * @return the answer
    188      *
    189      * @since 1.9.5
    190      */
    191     public static <T> Answer<T> returnsElementsOf(Collection<?> elements) {
    192         return (Answer<T>) new ReturnsElementsOf(elements);
    193     }
    194 }
    195