19

我正在使用AssertJ,并且我试图断言两个List<String>包含相同的字符串,而忽略了顺序。

List<String> expected = Arrays.asList("Something-6144-77.pdf", "d-6144-77.pdf", "something-6144-78.pdf", "Something-6144-8068.pdf");
List<String> actual = new ArrayList<String>();

assertThat(actual.size()).isEqualTo(expected.size());

// This line gives the error: "The method containsExactlyInAnyOrder(String...) in the type ListAssert<String> is not applicable for the arguments (List<String>)"
assertThat(actual).containsExactlyInAnyOrder(expected);

如何修复尝试使用时出现的以下编译错误containsExactlyInAnyOrder()

“ListAssert 类型中的方法 containsExactlyInAnyOrder(String...) 不适用于参数 (List)”

4

4 回答 4

16

两个答案(由 jlordodasblinkenlight 提供)都有效,但都是解决方法,而不是正确的方法。

AssertJ 库中有一个方法可以专门检查 a 是否List包含另一个 中的所有值,无论顺序如何Iterable。它被称为containsOnlyElementsOf()

public SELF containsOnlyElementsOf(Iterable<? extends ELEMENT> iterable)

与 : 的语义相同,ObjectEnumerableAssert.containsOnly(Object[])验证实际包含给定迭代的所有元素,没有其他元素,以任何顺序。

例子 :

Iterable<Ring> rings = newArrayList(nenya, vilya);

// assertion will pass
assertThat(rings).containsOnlyElementsOf(newLinkedList(nenya, vilya)) .containsOnlyElementsOf(newLinkedList(nenya, nenya, vilya, vilya));

// assertion will fail as actual does not contain narya
assertThat(rings).containsOnlyElementsOf(newLinkedList(nenya, vilya, narya));
// assertion will fail as actual contains nenya assertThat(rings).containsOnlyElementsOf(newLinkedList(vilya));

因此,此方法是您应该使用的方法,如下所示。无需将您的转换或转换ListArray.

assertThat(actual).containsOnlyElementsOf(expected);

作为旁注,您对列表大小的断言是多余的:

assertThat(actual.size()).isEqualTo(expected.size());

这已经包含在列表包含相同元素的断言中。

最后,如果你确实需要断言一个列表有一个特定的站点,AssertJ 有一个内置的方法(hasSameSizeAs()):

assertThat(actual).hasSameSizeAs(expected);
于 2017-05-29T10:56:20.967 回答
12

错误消息为您提供了解决方案:

The method containsExactlyInAnyOrder(String...)

String...是任意数量的字符串,但也可以作为数组传递:

assertThat(actual).containsExactlyInAnyOrder((String[]) expected.toArray(new String[expected.size()]));

强制转换在这里是必要的,并且该代码是在假设expected创建的元素与您的示例不同的情况下给出的,因为将数组转换为列表并返回是没有意义的。

这里有一些关于varargs的文档(Arbitrary number of arguments, the ...):https ://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html

于 2017-03-27T20:51:07.457 回答
4

由于该方法需要String...,因此您应该传递一个数组而不是列表:

String[] expected = new String[] {
    "Something-6144-77.pdf"
,   "d-6144-77.pdf"
,   "something-6144-78.pdf"
,   "Something-6144-8068.pdf"
};

或使用内联项目列表调用它:

assertThat(actual).containsExactlyInAnyOrder(
    "Something-6144-77.pdf"
,   "d-6144-77.pdf"
,   "something-6144-78.pdf"
,   "Something-6144-8068.pdf"
);
于 2017-03-27T20:49:08.853 回答
2

在较新版本的assertj中有一个containsExactlyInAnyOrderElementsOf正是为了这个目的。你的例子归结为

assertThat(actual).containsExactlyInAnyOrderElementsOf(expected);
于 2019-10-29T12:24:13.857 回答