web-dev-qa-db-ja.com

順序を無視して、2つのLists <String>が等しいと断言する方法

私は AssertJ を使用していますが、2つの_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 ...)は引数(リスト)には適用できません"

11
Catfish

エラーメッセージはあなたに解決策を与えます:

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

4
jlordo

答え( by jlordo および by dasblinkenlight )はどちらも機能しますが、正しい方法ではなく回避策です。

AssertJライブラリには、Listに順序に関係なく別のIterableのすべての値が含まれているかどうかを具体的にチェックするメソッドがあります。それは containsOnlyElementsOf() と呼ばれます:

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

ObjectEnumerableAssert.containsOnly(Object[])と同じセマンティックス:actualが、指定されたイテラブルのすべての要素を含み、それ以外は何も含まれていないことを確認します。

例:

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);
_
8
Magnilex

メソッドは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"
);
4
dasblinkenlight

assertj の新しいバージョンでは、まさにこの目的のために containsExactlyInAnyOrderElementsOf があります。あなたの例は次のように要約されます

assertThat(actual).containsExactlyInAnyOrderElementsOf(expected);
0
dastrobu