Stubbing метод, который принимает Class <T> как параметр с Mockito
Существует общий метод, который принимает класс как параметр, и у меня возникают проблемы с его запуском с помощью Mockito. Метод выглядит следующим образом:
public <U extends Enum<U> & Error, T extends ServiceResponse<U>> T validate(
Object target, Validator validator, Class<T> responseClass,
Class<U> errorEnum);
Это ужасный бог, по крайней мере для меня... Я мог представить себе жизнь без него, но остальная база кода счастливо использует его...
Я собирался, в моем unit test, заглушить этот метод, чтобы вернуть новый пустой объект. Но как мне это сделать с помощью mockito? Я пробовал:
when(serviceValidatorStub.validate(
any(),
isA(UserCommentRequestValidator.class),
UserCommentResponse.class,
UserCommentError.class)
).thenReturn(new UserCommentResponse());
но поскольку я смешиваю и сопоставляю совпадения и исходные значения, я получаю "org.mockito.exceptions.misusing.InvalidUseOfMatchersException: недопустимое использование аргументов!"
Ответы
Ответ 1
Проблема заключается в том, что вы не можете смешивать аргументы аргументов и реальные аргументы в насмешливом вызове. Итак, скорее сделайте следующее:
when(serviceValidatorStub.validate(
any(),
isA(UserCommentRequestValidator.class),
eq(UserCommentResponse.class),
eq(UserCommentError.class))
).thenReturn(new UserCommentResponse());
Обратите внимание на использование аргумента eq()
для сопоставления равенства.
см. https://static.javadoc.io/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html#eq(T)
Кроме того, вы можете использовать аргумент аргумента same()
для типов Class<?>
- это совпадает с тем же идентификатором, что и оператор Java ==
.
Ответ 2
Для того, чтобы выполнить один и тот же поток, если кто-то хочет выровнять метод, который принимает аргумент Class как аргумент, но не заботится о типе, или нужно, чтобы многие типы были пропущены одинаково, вот еще один решение:
private class AnyClassMatcher extends ArgumentMatcher<Class<?>> {
@Override
public boolean matches(final Object argument) {
// We always return true, because we want to acknowledge all class types
return true;
}
}
private Class<?> anyClass() {
return Mockito.argThat(new AnyClassMatcher());
}
а затем вызовите
Mockito.when(mock.doIt(this.anyClass())).thenCallRealMethod();
Ответ 3
Ницца @Аш. Я использовал ваш общий класс, чтобы подготовить ниже.
Это можно использовать, если мы хотим подготовить макет определенного типа. (Не экземпляр)
private Class<StreamSource> streamSourceClass() {
return Mockito.argThat(new ArgumentMatcher<Class<StreamSource>>() {
@Override
public boolean matches(Object argument) {
// TODO Auto-generated method stub
return false;
}
});
}
Использование:
Mockito.when(restTemplate.getForObject(Mockito.anyString(),
**streamSourceClass(),**
Mockito.anyObject));