All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fitbur.mockito.AdditionalAnswers Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
/*
 * Copyright (c) 2007 Mockito contributors
 * This program is made available under the terms of the MIT License.
 */
package com.fitbur.mockito;

import com.fitbur.mockito.internal.stubbing.answers.AnswerFunctionalInterfaces;
import com.fitbur.mockito.internal.stubbing.answers.ReturnsArgumentAt;
import com.fitbur.mockito.internal.stubbing.answers.ReturnsElementsOf;
import com.fitbur.mockito.internal.stubbing.defaultanswers.ForwardsInvocations;
import com.fitbur.mockito.stubbing.Answer;

import java.util.Collection;

/**
 * Additional answers provides factory methods for answers.
 *
 * 

Currently offer answers that can return the parameter of an invocation at a certain position, * along with answers that draw on a strongly typed interface from {@link AnswerFunctionalInterfaces} * to provide a neater way to write custom answers that either return a value or are void. * *

See factory methods for more information : {@link #returnsFirstArg}, {@link #returnsSecondArg}, * {@link #returnsLastArg}, {@link #returnsArgAt}, {@link #answer} and {@link #answerVoid} * * @since 1.9.5 */ @SuppressWarnings("unchecked") public class AdditionalAnswers { private static final ReturnsArgumentAt RETURNS_FIRST_ARGUMENT = new ReturnsArgumentAt(0); private static final ReturnsArgumentAt RETURNS_SECOND_ARGUMENT = new ReturnsArgumentAt(1); private static final ReturnsArgumentAt RETURNS_LAST_ARGUMENT = new ReturnsArgumentAt(-1); /** * Returns the first parameter of an invocation. * *

* This additional answer could be used at stub time using the * then|do|will{@link com.fitbur.mockito.stubbing.Answer} methods. For example : *

* *
given(carKeyFob.authenticate(carKey)).will(returnsFirstArg());
     * doAnswer(returnsFirstArg()).when(carKeyFob).authenticate(carKey)
* * @param Return type of the invocation. * @return Answer that will return the first argument of the invocation. * * @since 1.9.5 */ public static Answer returnsFirstArg() { return (Answer) RETURNS_FIRST_ARGUMENT; } /** * Returns the second parameter of an invocation. * *

* This additional answer could be used at stub time using the * then|do|will{@link com.fitbur.mockito.stubbing.Answer} methods. For example : *

* *
given(trader.apply(leesFormula, onCreditDefaultSwap)).will(returnsSecondArg());
     * doAnswer(returnsSecondArg()).when(trader).apply(leesFormula, onCreditDefaultSwap)
* * @param Return type of the invocation. * @return Answer that will return the second argument of the invocation. * * @since 1.9.5 */ public static Answer returnsSecondArg() { return (Answer) RETURNS_SECOND_ARGUMENT; } /** * Returns the last parameter of an invocation. * *

* This additional answer could be used at stub time using the * then|do|will{@link com.fitbur.mockito.stubbing.Answer} methods. For example : *

* *
given(person.remember(dream1, dream2, dream3, dream4)).will(returnsLastArg());
     * doAnswer(returnsLastArg()).when(person).remember(dream1, dream2, dream3, dream4)
* * @param Return type of the invocation. * @return Answer that will return the last argument of the invocation. * * @since 1.9.5 */ public static Answer returnsLastArg() { return (Answer) RETURNS_LAST_ARGUMENT; } /** * Returns the parameter of an invocation at the given position. * *

* This additional answer could be used at stub time using the * then|do|will{@link com.fitbur.mockito.stubbing.Answer} methods. For example : *

* *
given(person.remember(dream1, dream2, dream3, dream4)).will(returnsArgAt(3));
     * doAnswer(returnsArgAt(3)).when(person).remember(dream1, dream2, dream3, dream4)
* * @param Return type of the invocation. * @param position index of the argument from the list of arguments. * @return Answer that will return the argument from the given position in the argument's list * * @since 1.9.5 */ public static Answer returnsArgAt(int position) { return (Answer) new ReturnsArgumentAt(position); } /** * An answer that directly forwards the calls to the delegate. The delegate may or may not be of the same type as the mock. * If the type is different, a matching method needs to be found on delegate type otherwise an exception is thrown. *

* Useful for spies or partial mocks of objects that are difficult to mock * or spy using the usual spy API. Possible use cases: *

    *
  • Final classes but with an interface
  • *
  • Already custom proxied object
  • *
  • Special objects with a finalize method, i.e. to avoid executing it 2 times
  • *
* For more details including the use cases reported by users take a look at * issue 145. *

* The difference with the regular spy: *

    *
  • * The regular spy ({@link Mockito#spy(Object)}) contains all state from the spied instance * and the methods are invoked on the spy. The spied instance is only used at mock creation to copy the state from. * If you call a method on a regular spy and it internally calls other methods on this spy, those calls are remembered * for verifications, and they can be effectively stubbed. *
  • *
  • * The mock that delegates simply delegates all methods to the delegate. * The delegate is used all the time as methods are delegated onto it. * If you call a method on a mock that delegates and it internally calls other methods on this mock, * those calls are not remembered for verifications, stubbing does not have effect on them, too. * Mock that delegates is less powerful than the regular spy but it is useful when the regular spy cannot be created. *
  • *
* An example with a final class that we want to delegate to: *

*


     *   final class DontYouDareToMockMe implements list { ... }
     *
     *   DontYouDareToMockMe awesomeList = new DontYouDareToMockMe();
     *
     *   List mock = mock(List.class, delegatesTo(awesomeList));
     * 
* *

* This feature suffers from the same drawback as the spy. * The mock will call the delegate if you use regular when().then() stubbing style. * Since the real implementation is called this might have some side effects. * Therefore you should to use the doReturn|Throw|Answer|CallRealMethod stubbing style. Example: * *


     *   List listWithDelegate = mock(List.class, AdditionalAnswers.delegatesTo(awesomeList));
     *
     *   //Impossible: real method is called so listWithDelegate.get(0) throws IndexOutOfBoundsException (the list is yet empty)
     *   when(listWithDelegate.get(0)).thenReturn("foo");
     *
     *   //You have to use doReturn() for stubbing
     *   doReturn("foo").when(listWithDelegate).get(0);
     * 
* * @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). * The only requirement is that the instance should have compatible method signatures including the return values. * Only the methods that were actually executed on the mock need to be present on the delegate type. * @return the answer * * @since 1.9.5 */ public static Answer delegatesTo(Object delegate) { return (Answer) new ForwardsInvocations(delegate); } /** * Returns elements of the collection. Keeps returning the last element forever. * Might be useful on occasion when you have a collection of elements to return. *

*


     *   //this:
     *   when(mock.foo()).thenReturn(1, 2, 3);
     *
     *   //is equivalent to:
     *   when(mock.foo()).thenAnswer(new ReturnsElementsOf(Arrays.asList(1, 2, 3)));
     * 
* * @param elements The collection of elements to return. * @return the answer * * @since 1.9.5 */ public static Answer returnsElementsOf(Collection elements) { return (Answer) new ReturnsElementsOf(elements); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - which is expected to return something * @param return type * @param input parameter type 1 * @return the answer object to use */ public static Answer answer(AnswerFunctionalInterfaces.Answer1 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - a void method * @param input parameter type 1 * @return the answer object to use */ public static Answer answerVoid(AnswerFunctionalInterfaces.VoidAnswer1 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - which is expected to return something * @param return type * @param input parameter type 1 * @param input parameter type 2 * @return the answer object to use */ public static Answer answer(AnswerFunctionalInterfaces.Answer2 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - a void method * @param input parameter type 1 * @param input parameter type 2 * @return the answer object to use */ public static Answer answerVoid(AnswerFunctionalInterfaces.VoidAnswer2 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - which is expected to return something * @param return type * @param input parameter type 1 * @param input parameter type 2 * @param input parameter type 3 * @return the answer object to use */ public static Answer answer(AnswerFunctionalInterfaces.Answer3 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - a void method * @param input parameter type 1 * @param input parameter type 2 * @param input parameter type 3 * @return the answer object to use */ public static Answer answerVoid(AnswerFunctionalInterfaces.VoidAnswer3 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - which is expected to return something * @param return type * @param input parameter type 1 * @param input parameter type 2 * @param input parameter type 3 * @param input parameter type 4 * @return the answer object to use */ public static Answer answer(AnswerFunctionalInterfaces.Answer4 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - a void method * @param input parameter type 1 * @param input parameter type 2 * @param input parameter type 3 * @param input parameter type 4 * @return the answer object to use */ public static Answer answerVoid(AnswerFunctionalInterfaces.VoidAnswer4 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * @param answer interface to the answer - which is expected to return something * @param return type * @param input parameter type 1 * @param input parameter type 2 * @param input parameter type 3 * @param input parameter type 4 * @param input parameter type 5 * @return the answer object to use */ public static Answer answer(AnswerFunctionalInterfaces.Answer5 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } /** * Creates an answer from a functional interface - allows for a strongly typed answer to be created * ideally in Java 8 * * @param answer interface to the answer - a void method * @param input parameter type 1 * @param input parameter type 2 * @param input parameter type 3 * @param input parameter type 4 * @param input parameter type 5 * @return the answer object to use */ public static Answer answerVoid(AnswerFunctionalInterfaces.VoidAnswer5 answer) { return AnswerFunctionalInterfaces.toAnswer(answer); } }