Reputation: 9373
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);
Upvotes: 4
Views: 10541
Reputation: 5095
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...
Upvotes: 10
Reputation: 14999
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;
}
}
Upvotes: 7
Reputation: 15622
You can use thenAnswer()
as described on mockitos web site.
when(mock.myMethod()).thenAnswer(new Answer<Integer>(){
private final int seed=100;
private int previousVal=0;
public Integer answer(InvocationOnMock invocation) throws Throwable {
int currentVal= previousVal;
previousVal += seed;
return currentVal;
}
});
but usually this requirement arises from a flawed testing approach:
Each method in a unittest class should verify a single expectation on the code under test. Therefore there should be no need for such "dynamic" test value generation.
Upvotes: 2