Is there a way to enumerate the items in a list within mockito's thenReturn function so I return each item in a list. So far I've done this:
List<Foo> returns = new ArrayList<Foo>();
//populate returns list
Mockito.when( /* some function is called */ ).thenReturn(returns.get(0), returns.get(1), returns.get(2), returns.get(3));
This works exactly how I want it to. Each time the function is called, it returns a different object from the list, e.g get(1)
, get(2)
etc.
But I want to simplify this and make it more dynamic to any size list in case I have a list with size say 100. I tried something like this:
Mockito.when( /* some function is called */ ).thenReturn(
for(Foo foo : returns) {
return foo;
}
);
I've tried this as well:
Mockito.when(service.findFinancialInstrumentById(eq(1L))).thenReturn(
for (int i=0; i<returns.size(); i++) {
returns.get(i);
}
);
But this doesn't work....so how do I enumerate this list within the thenReturn
....I've come across other methods to like then
or answer
but I'm not sure which one works best in this scenario.
The thenReturn() method signature is
thenReturn(T value, T... values)
So it takes an instance of T, followed by a vararg T..., which is syntactic sugar for an array. So you can use
when(foo.bar()).thenReturn(list.get(0),
list.subList(1, list.size()).toArray(new Foo[]{}));
But a cleaner solution would be to create an Answer implementation that takes a List as argument and answers the next element of the list every time it's used. And then use
when(foo.bar()).thenAnswer(new SequenceAnswer<>(list));
For example:
private static class SequenceAnswer<T> implements Answer<T> {
private Iterator<T> resultIterator;
// the last element is always returned once the iterator is exhausted, as with thenReturn()
private T last;
public SequenceAnswer(List<T> results) {
this.resultIterator = results.iterator();
this.last = results.get(results.size() - 1);
}
@Override
public T answer(InvocationOnMock invocation) throws Throwable {
if (resultIterator.hasNext()) {
return resultIterator.next();
}
return last;
}
}
Another way of doing it (but personally, I prefer JB Nizet SequenceAnswer idea), would be something like this...
OngoingStubbing stubbing = Mockito.when(...);
for(Object obj : list) {
stubbing = stubbing.thenReturn(obj);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With