Ответ 1
Mockito/Hamcrest и общие классы
Да, это общая проблема с Mockito/Hamcrest. Обычно использование isA()
с общими классами вызывает предупреждение.
Существуют предустановленные комбинации Mockito для наиболее общих классов: anyList(), anyMap()
, anySet()
и anyCollection()
.
Предложения:
anyIterable() в Mockito 2.1.0
Mockito 2.1.0 добавил новый метод anyIterable() для соответствия Iterables:
when(client.runTask(anyString(), anyString(), anyIterable()).thenReturn(...)
Игнорировать в Eclipse
Если вы просто хотите избавиться от предупреждения в Eclipse. Опция существует, поскольку Eclipse Indigo:
Окно > Настройки > Java > Компилятоp > Ошибки/предупреждения > Общие типы > Игнорировать неизбежные типичные проблемы типа
Быстрое исправление с помощью @SuppressWarnings
Я предлагаю вам сделать это, если у вас есть проблема только один раз. Я лично не помню, чтобы когда-либо понадобился isA(Iterable.class)
.
Как говорит Даниэль Праден, вы можете ограничить @SuppressWarnings
локальной переменной или вспомогательным методом.
Использовать общий ключ isA() с TypeToken
Это решает проблему навсегда. Но у него есть два недостатка:
- Синтаксис не слишком хорош и может смутить некоторых людей.
- У вас есть дополнительная зависимость от библиотеки, предоставляющей класс
TypeToken
. Здесь я использовал TypeToken класс из Guava. Также существует классTypeToken
в Gson и aGenericType
в JAX-RS.
Использование общего шаблона:
import static com.arendvr.matchers.InstanceOfGeneric.isA;
import static org.mockito.ArgumentMatchers.argThat;
// ...
when(client.runTask(anyString(), anyString(), argThat(isA(new TypeToken<Iterable<Integer>>() {}))))
.thenReturn(...);
Общий класс сопряжения:
package com.arendvr.matchers;
import com.google.common.reflect.TypeToken;
import org.mockito.ArgumentMatcher;
public class InstanceOfGeneric<T> implements ArgumentMatcher<T> {
private final TypeToken<T> typeToken;
private InstanceOfGeneric(TypeToken<T> typeToken) {
this.typeToken = typeToken;
}
public static <T> InstanceOfGeneric<T> isA(TypeToken<T> typeToken) {
return new InstanceOfGeneric<>(typeToken);
}
@Override
public boolean matches(Object item) {
return item != null && typeToken.getRawType().isAssignableFrom(item.getClass());
}
}