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