Mockito isA(Class<T> clazz) 如何解决类型安全问题? [英] Mockito isA(Class<T> clazz) How to resolve type safety?

查看:29
本文介绍了Mockito isA(Class<T> clazz) 如何解决类型安全问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的测试中,我有以下几行:

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 a TypeToken class in Gson and a GenericType 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&lt;T&gt; clazz) 如何解决类型安全问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆