2011-03-28 4 views
39

Существует общий метод, который принимает класс как параметр, и у меня возникают проблемы с его запуском с помощью Mockito. Метод выглядит следующим образом:Stubbing метод, который принимает класс <T> как параметр с Mockito

public <U extends Enum<U> & Error, T extends ServiceResponse<U>> T validate(
    Object target, Validator validator, Class<T> responseClass, 
    Class<U> errorEnum); 

Это бог ужасно, по крайней мере для меня ... Я мог себе представить жизнь без него, но остальная часть базы кода счастливо использует его ...

Я в моем модульном тесте, запустите этот метод, чтобы вернуть новый пустой объект. Но как мне это сделать с помощью mockito? Я пробовал:

, но так как я смешивания и сопоставления matchers и сырые значения, я получаю «org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Неправильное использование аргумента matchers»

ответ

71

Проблема в том, что вы не можете смешивать аргументы аргументов и реальные аргументы в издеваемом вызове. Таким образом, вместо этого:

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.

+0

работал как шарм, очень хороший ответ. Хорошо объяснил слишком –

+0

Могущественный благодарный! –

+0

Действительно. Но мне интересно, можно ли улучшить Mockito, чтобы пользователи могли «смешивать аргументы и реальные аргументы»; если Unitils Mock может это сделать, то это должно быть технически возможно. –

2

Для того, чтобы завершить работу над одной и той же нитью, если кто-то захочет заимствовать метод, который принимает аргумент класса как класс, но не заботится о типе, или нужно, чтобы многие типы были обрезаны одинаково, здесь другое решение:

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(); 
0

Nice один @Ash. Я использовал ваш общий класс, чтобы подготовить ниже. Это может быть использовано, если мы хотим, чтобы подготовить макет определенного типа (не экземпляр)

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)); 
Смежные вопросы