带有通配符的列表上的AssertJ`containsExactly`断言 [英] AssertJ `containsExactly` assertion on list with wildcard

查看:348
本文介绍了带有通配符的列表上的AssertJ`containsExactly`断言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个吸气剂,返回带有通配符的列表:

I have a getter returning a List with a wildcard:

import java.util.List;

public interface Foo {
    List<? extends Bar> getList();
}

Bar是另一个接口.

当我这样用AssertJ编写断言时:

When I write an assertion with AssertJ like this:

assertThat(foo.getList()).containsExactly(bar1, bar3);

我的完整用法是链接一个usingElementComparator并提供一个Comparator<Bar>来比较预期的Bar实例.

my complete usage is to chain a usingElementComparator and to provide a Comparator<Bar> to compare the expected Bar instances.

Comparator<Bar> comparator = createBarComparator()
assertThat(foo.getList()).usingElementComparator(comparator).containsExactly(bar1, bar3);

我收到此编译错误:

ListAssert类型的方法containsExactly(capture#46-of吗?扩展了Bar ...)不适用于参数(Bar,Bar)

The method containsExactly(capture#46-of ? extends Bar...) in the type ListAssert is not applicable for the arguments (Bar, Bar)


我的第一个解决方案是投射结果:


My first solution is to cast the result:

assertThat((List<Bar>)foo.getList()).containsExactly(bar1, bar3);

然后我得到警告:

类型安全:从列表到列表的强制转换

Type safety: Unchecked cast from List to List

可以使用@SuppressWarnings("unchecked")删除警告,但中间的强制类型转换不能使断言真正可读.

Warning can be removed with @SuppressWarnings("unchecked"), but still the cast in the middle do not make the assertion really readable.

我的第二个解决方案是指出ELEMENT通用参数的值:

My second solution is to indicate the value the ELEMENT generic parameter:

Assertions.<Bar>assertThat(foo.getList()).containsExactly(bar1, bar3);

好一点,但也不太好(不可能静态导入,该行的开头不利于可读性)

A little better, but also not that nice (no static import possible, the beginning of the line do not facilitate the readability)

我想我正在寻找其他assertThat列表方法,其中可以将类类型指定为第二个参数:

I guess I am looking for an other assertThat method for list, where the class type can be specified as second parameter:

@CheckReturnValue
public static <ELEMENT> ListAssert<ELEMENT> assertThat(List<? extends ELEMENT> actual, Class<ELEMENT> c) {
    return AssertionsForInterfaceTypes.assertThat(actual);
}

这样,我应该可以编写如下内容:

This way I should be able to write something like this:

Assertions.assertThat(foo.getList(), Bar.class).containsExactly(bar1, bar3);

推荐答案

以前用于Oracle JDK 7编译器,但这实际上是编译器中的错误,已在Java 8 JDK中修复,因此出现编译错误是正常行为(尽管找不到bug参考).

That used to work with the Oracle JDK 7 compiler but this was actually a bug in the compiler, this has been fixed in Java 8 JDK so having the compilation error is the normal behavior (can't find the bug reference though).

我很乐意支持,但是我不确定在AssertJ中是否可以实现,除非删除集合断言中的所有泛型用法.

I would be happy to support but I'm not sure this is possible in AssertJ except by removing all generics usage in collections assertions.

assertThat(List, Class) already exists but for another purpose so no luck for that option.

一种可能的破解方法是定义您自己的assertThat方法,如下所示:

A possible hack is to define your own assertThat method like that:

public static <T> ListAssert<Object> assertThat(final List<T> list) {
    return Assertions.assertThat(list);
}

诀窍是返回ListAssert<Object>.

尽管我了解编译错误的原因,但我不同意只读方法.

Although I understand the rationale of the compilation error I disagree with it for read only method.

这篇关于带有通配符的列表上的AssertJ`containsExactly`断言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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