问题
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.
回答1:
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);
}
回答2:
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;
}
}
来源:https://stackoverflow.com/questions/33310960/java-enumerating-list-in-mockitos-thenreturn