One typically defines return values for a Mockito mock during compile time, i.e. statically:
MyClass myClass = Mockito.mock(MyClass.class);
when(myClass.myMethod()).thenReturn(0, 100, 200, ...);
Is there a way to do this dynamically by supplying a seed and a function, e.g.:
when(mock.myMethod()).thenReturn(seed, previousVal -> previousVal + 100);
The easiest way may be to combine Mockitos Answer with lambdas, streams and iterators. The resulting code is
Iterator<Integer> values = Stream.iterate(0, n -> n + 100).iterator();
when(myClass.myMethod()).thenAnswer(i -> values.next());
The code can be made a little more efficient if you use an IntStream and a PrimitiveIterator.OfInt as the iterator type, but that is probably overkill for a unit test...
Yes, you can return an org.mockito.stubbing.Answer
.
class AddingAnswer implements Answer {
int current = 0;
public Object answer(InvocationOnMock invocation) {
int result = current;
current += 100;
return result;
}
}
which you can then wire to your mock like this
Answer answer = new AddingAnswer();
when(myClass.myMethod()).then(answer);
Or in the generic version you want
class DynamicAnswer<T> implements Answer {
T currentValue;
UnaryOperator<T> adjustment;
public DynamicAnswer(T seed, UnaryOperator<T> ad) {
currentValue = seed;
adjustment = ad;
}
public Object answer(InvocationOnMock invocation) {
T result = currentValue;
currentValue = adjustment.apply(currentValue);
return result;
}
}
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