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