在我的测试中,我有以下内容:
when(client.runTask(anyString(), anyString(), isA(Iterable.class)).thenReturn(...)
isA(Iterable.class)
产生警告,它需要未经检查的转换才能符合Iterable<Integer>
。那是什么语法?isA(Iterable<Integer>.class)
isA((Iterable<Integer>)Iterable.class
不工作。
有什么建议么?
最佳答案
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以来存在选项:
使用@SuppressWarnings快速修复
如果您只有一次问题,我建议您这样做。我个人不记得曾经需要
isA(Iterable.class)
。正如Daniel Pryden所说,您可以将
@SuppressWarnings
限制为局部变量或辅助方法。对TypeToken使用通用的isA()匹配器
这样可以彻底解决问题。但这有两个缺点:
TypeToken
类的库有其他依赖性。在这里,我使用了TypeToken class from Guava。 Gson中还有一个TypeToken
类,而JAX-RS中还有一个GenericType
。 使用通用匹配器:
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());
}
}