Mockito isA(Class<T> clazz) 如何解决类型安全问题? [英] Mockito isA(Class<T> clazz) How to resolve type safety?
问题描述
在我的测试中,我有以下几行:
in my test I have the following line:
when(client.runTask(anyString(), anyString(), isA(Iterable.class)).thenReturn(...)
isA(Iterable.class)
产生警告,它需要未经检查的转换以符合 Iterable
.那是什么语法?
isA(Iterable.class)
produces warning that it needs unchecked conversion to conform to Iterable<Integer>
. What is syntax for that?
isA(Iterable<Integer>.class)
isA((Iterable<Integer>)Iterable.class
不工作.
有什么建议吗?
推荐答案
Mockito/Hamcrest 和泛型类
是的,这是 Mockito/Hamcrest 的普遍问题.通常将 isA()
与泛型类一起使用会产生警告.
Mockito/Hamcrest and generic classes
Yes, this is a general problem with Mockito/Hamcrest. Generally using isA()
with generic classes produces a warning.
对于最常见的通用类有预定义的 Mockito 匹配器:anyList()、anyMap()
、anySet()
和 anyCollection()
.
There are predifined Mockito matchers for the most common generic classes: anyList(), anyMap()
, anySet()
and anyCollection()
.
建议:
Mockito 2.1.0 添加了一个新的 anyIterable() 匹配 Iterable 的方法:
Mockito 2.1.0 added a new anyIterable() method for matching Iterables:
when(client.runTask(anyString(), anyString(), anyIterable()).thenReturn(...)
在 Eclipse 中忽略
如果您只是想摆脱 Eclipse 中的警告.选项存在于 日蚀靛蓝:
Window > Preferences > Java > Compiler > Errors/Warnings > Generic类型 > 忽略不可避免的泛型问题
Window > Preferences > Java > Compiler > Errors/Warnings > Generic types > Ignore unavoidable generic type problems
使用@SuppressWarnings 快速修复
如果您只遇到一次问题,我建议您这样做.我个人不记得曾经需要 isA(Iterable.class)
.
正如 Daniel Pryden 所说,您可以将 @SuppressWarnings
限制为局部变量或辅助方法.
As Daniel Pryden says, you can limit the @SuppressWarnings
to a local variable or a helper method.
这彻底解决了问题.但它有两个缺点:
This solves the problem for good. But it has two disadvantages:
- 语法不太漂亮,可能会让一些人感到困惑.
- 您对提供
TypeToken
类的库有额外的依赖.在这里,我使用了 TypeToken 类番石榴.Gson 中还有一个TypeToken
类,JAX-RS 中还有一个GenericType
类.
- The syntax is not too pretty and might confuse some people.
- You have an additional dependency on the library providing the
TypeToken
class. Here I used the TypeToken class from Guava. There's also aTypeToken
class in Gson and aGenericType
in 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());
}
}
这篇关于Mockito isA(Class<T> clazz) 如何解决类型安全问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!