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