Reputation: 19445
The class that I test receive a client wrapper:
The tested class (snippest)
private ClientWrapper cw
public Tested(ClientWrapper cw) {
this.cw = cw;
}
public String get(Request request) {
return cw.getClient().get(request);
}
The test initialization:
ClientWrapper cw = Mockito.mock(ClientWrapper.class);
Client client = Mockito.mock(Client.class);
Mockito.when(cw.getClient()).thenReturn(client);
//Here is where I want to alternate the return value:
Mockito.when(client.get(Mockito.any(Request.class))).thenReturn("100");
In the exmaple I always return "100", but the Request have an attribute id
and I would like to return different values to client.get(Request)
based on the request.getId()
value.
How can I do it?
Upvotes: 21
Views: 40393
Reputation: 9058
You could create an ArgumentMatcher
to let you match the Request
by id.
So the argument matcher would be like this:
import org.mockito.ArgumentMatcher;
public class IsRequestWithId implements ArgumentMatcher<Request> {
private final int id;
public IsRequestWithId(int id) {
this.id = id;
}
@Override
public boolean matches(Object arg) {
Request request = (Request)arg;
return id == request.getId();
}
}
Then you could use it like:
Mockito.when(client.get(Mockito.argThat(new IsRequestWithId(1)))).thenReturn("100");
Mockito.when(client.get(Mockito.argThat(new IsRequestWithId(2)))).thenReturn("200");
Otherwise using an Answer
would also work, but using an ArgumentMatcher
lets you keep the code more "declarative".
Upvotes: 9
Reputation: 5474
In order to do it right and with minimal code you have to use the ArgumentMatcher
, lambda expression & don't forget to do a null check on the filters members in the ArgumentMatcher
lambda (especially if you have more than one mock with the same ArgumentMatcher
).
Customized argument matcher:
private ArgumentMatcher<Request> matchRequestId(final String target) {
return request -> request != null &&
target.equals(request.getId());
}
Usage:
given(client.get(argThat(matchRequestId("1")))).willReturn("100");
given(client.get(argThat(matchRequestId("2")))).willReturn("200");
Upvotes: 9
Reputation: 16039
You can use Mockito's answers, so instead of:
Mockito.when(client.get(Mockito.any(Request.class))).thenReturn("100");
write:
Mockito.when(client.get(Mockito.any(Request.class)))
.thenAnswer(new Answer() {
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
return "called with arguments: " + args;
}
});
Upvotes: 42