com.fitbur.mockito.AdditionalAnswers Maven / Gradle / Ivy
/*
* 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);
}
}