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< Integer>
。这是什么语法?
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匹配器最常见的通用类: yList(), anyMap()
, anySet()
和 anyCollection( )
。
There are predifined Mockito matchers for the most common generic classes: anyList(), anyMap()
, anySet()
and anyCollection()
.
建议:
Mockito 2.1.0添加了一个新的 anyIterable()匹配Iterables的方法:
Mockito 2.1.0 added a new anyIterable() method for matching Iterables:
when(client.runTask(anyString(), anyString(), anyIterable()).thenReturn(...)
在Eclipse中忽略
如果你只想摆脱Eclipse中的警告。选项存在,因为 Eclipse Indigo :
窗口>首选项> Java>编译器>错误/警告>通用
类型>忽略不可避免的泛型类型问题
Window > Preferences > Java > Compiler > Errors/Warnings > Generic types > Ignore unavoidable generic type problems
使用@SuppressWarnings进行快速修复
I如果您只遇到一次问题,建议您这样做。我个人不记得曾经需要 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屋!