Как вернуть разное значение в Mockito на основе атрибута параметра?
Класс, который я тестирую, получает клиентскую оболочку:
Проверенный класс (snippest)
private ClientWrapper cw
public Tested(ClientWrapper cw) {
this.cw = cw;
}
public String get(Request request) {
return cw.getClient().get(request);
}
Инициализация теста:
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");
В exmaple я всегда возвращаю "100", но Request имеет атрибут id
, и я хотел бы вернуть разные значения в client.get(Request)
на основе значения request.getId()
.
Как я могу это сделать?
Ответы
Ответ 1
Вы можете использовать ответы Mockito, поэтому вместо:
Mockito.when(client.get(Mockito.any(Request.class))).thenReturn("100");
записи:
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;
}
});
Ответ 2
Вы можете создать ArgumentMatcher
, чтобы он соответствовал Request
по идентификатору.
Таким образом, сопоставление аргументов будет выглядеть следующим образом:
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();
}
}
Тогда вы можете использовать его как:
Mockito.when(client.get(Mockito.argThat(new IsRequestWithId(1)))).thenReturn("100");
Mockito.when(client.get(Mockito.argThat(new IsRequestWithId(2)))).thenReturn("200");
В противном случае использование Answer
также будет работать, но использование ArgumentMatcher
позволит вам сделать код более "декларативным".
Ответ 3
Чтобы сделать это правильно и с минимальным кодом, вы должны использовать выражение ArgumentMatcher
, лямбда и не забыть выполнить нулевую проверку членов фильтров в ArgumentMatcher
лямбда (особенно если у вас более одного макета с тем же ArgumentMatcher
).
Индивидуальный сортировщик аргументов:
private ArgumentMatcher<Request> matchRequestId(final String target) {
return request -> request != null &&
target.equals(request.getId());
}
Использование:
given(client.get(argThat(matchRequestId("1")))).willReturn("100");
given(client.get(argThat(matchRequestId("2")))).willReturn("200");