Mockito/Hamcrest 和泛型类
是的,这是 Mockito/Hamcrest 的普遍问题。通常isA()
与泛型类一起使用会产生警告。
最常见的泛型类有预定义的 Mockito 匹配器:anyList()、anyMap()
和。anySet()
anyCollection()
建议:
Mockito 2.1.0 中的 anyIterable()
Mockito 2.1.0 添加了一个新的anyIterable()方法来匹配 Iterables:
when(client.runTask(anyString(), anyString(), anyIterable()).thenReturn(...)
在 Eclipse 中忽略
如果您只是想摆脱 Eclipse 中的警告。自Eclipse Indigo以来存在选项:
窗口 > 首选项 > Java > 编译器 > 错误/警告 > 泛型 > 忽略不可避免的泛型类型问题
使用@SuppressWarnings 快速修复
如果您只遇到一次问题,我建议您这样做。我个人不记得曾经需要一个isA(Iterable.class)
.
正如 Daniel Pryden 所说,您可以将其限制@SuppressWarnings
为局部变量或辅助方法。
使用带有 TypeToken 的通用 isA() 匹配器
这很好地解决了这个问题。但它有两个缺点:
- 语法不太漂亮,可能会使一些人感到困惑。
TypeToken
您对提供该类的库有额外的依赖关系。在这里,我使用了Guava 的 TypeToken 类。TypeToken
Gson 和GenericType
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());
}
}