I want a Mockito mock to return several values one after another when the same function is called on the mock, and have those values come from a list, instead of by writing them out as mock.thenReturn(1).thenReturn(2)
One way to do it is to roll my own function:
class A{
public int getVal() {return 0;}
}
class OneTest {
static void makeMockReturnSomeObjects(A mock, List<Integer> returnValues ) {
OngoingStubbing<Integer> stubbing = Mockito.when(mock.getVal());
for (Integer integer : returnValues) {
stubbing = stubbing.thenReturn(integer);
}
}
@Test
void test() {
A mock = Mockito.mock(A.class);
makeMockReturnSomeObjects(mock, List.of(1,2,3));
System.out.println(mock.getVal()); // prints 1
System.out.println(mock.getVal()); // prints 2
System.out.println(mock.getVal()); // prints 3
}
}
Is there a built in api or better way to accomplish this?
CodePudding user response:
Mockito offers the AdditionalAnswers class for doing something along those lines, to quote the javadocs:
Additional answers provides factory methods for answers
This allows for more dynamic configuration of Mock response behaviour.
As this answer to a similar question suggests, AdditionalAnswers.returnsElementsOf(Collection<?> elements)
could be used to supply the mock with a List of answers that will be used in order.
Caveat from the documentation should be noted there, it will automatically re-use the last element for all calls after iterating to the end, so if you want to simulate not returning answers after a certain point this will not work.
If I understand the documentation correctly, you could also customize the behaviour even further by utilizing the delegatesTo() method to relay the call to a (possibly stateful) object of your choice, or utilize the answer()
methods accepting functional interfaces for supplying a function that responds in a stateful manner.