如何断言两个列表 <String> 相等,忽略顺序

How to assert that two Lists<String> are equal, ignoring order

我正在使用 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() 时出现的以下编译错误?

"The method containsExactlyInAnyOrder(String...) in the type ListAssert is not applicable for the arguments (List)"

由于该方法需要 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"
);

报错信息给你解决方法:

The method containsExactlyInAnyOrder(String...)

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

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

此处需要强制转换,并且在假设 expected 元素的创建方式与您的示例不同的情况下给出了代码,因为将数组转换为列表并返回没有意义.

这里有一些文档varargs(任意数量的参数,...):https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html

两个答案 ( and ) 都有效,但只是解决方法,而不是正确的方法。

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

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

Same semantic as ObjectEnumerableAssert.containsOnly(Object[]) : verifies that actual contains all the elements of the given iterable and nothing else, in any order.

Example :

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));

因此,您应该使用这种方法,如下所示。无需将 List 转换为 Array.

assertThat(actual).containsOnlyElementsOf(expected);

附带说明一下,您对列表大小的断言是多余的:

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

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

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

assertThat(actual).hasSameSizeAs(expected);

在较新版本的 assertj there is a containsExactlyInAnyOrderElementsOf 中正是出于这个目的。 你的例子归结为

assertThat(actual).containsExactlyInAnyOrderElementsOf(expected);