javaunit-testingmockitostubbing

Have Mockito Return Varying Number of Different Values for Invocations


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?


Solution

  • 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.