web-dev-qa-db-ja.com

AssertEquals 2リストは順序を無視します

それは本当に簡単な質問だと思います。しかし、どういうわけか私はGoogleで答えを見つけることができません。

2つの文字列リストがあると仮定します。最初に"String A"と "String B"が含まれ、2番目に"String B"と "String A"が含まれます(順序の違いに注意してください)。 JUnitでテストして、まったく同じ文字列が含まれているかどうかを確認します。

順序を無視する文字列の等価性をチェックするアサートはありますか?指定された例では、org.junit.Assert.assertEqualsはAssertionErrorをスローします

Java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]>

回避策は、最初にリストをソートしてからアサーションに渡すことです。しかし、できるだけシンプルでクリーンなコードにする必要があります。

Hamcrest 1.JUnit 4.11Mockito 1.9.5を使用します。

63
kukis

Hamcrestを使用しているとおっしゃるように、Matchersコレクションの1つを選びます。

import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.junit.Assert.assertThat;

public class CompareListTest {

    @Test
    public void compareList() {
        List<String> expected = Arrays.asList("String A", "String B");
        List<String> actual = Arrays.asList("String B", "String A");

        assertThat("List equality without order", 
            actual, containsInAnyOrder(expected.toArray()));
    }

}
62
cheffe

List.containsAll をJUnitのassertTrueとともに使用して、最初のリストに2番目のリストのすべての要素が含まれていること、およびその逆を確認できます。

assertTrue(first.size() == second.size() && 
    first.containsAll(second) && second.containsAll(first));
46
robertoia

2次の複雑さを回避するソリューションを次に示します(リストを複数回繰り返します)。これは、Apache Commons CollectionUtilsクラスを使用して、リスト内の頻度カウント自体への各アイテムのマップを作成します。次に、2つのマップを単純に比較します。

Assert.assertEquals("Verify same metrics series",
    CollectionUtils.getCardinalityMap(expectedSeriesList),
    CollectionUtils.getCardinalityMap(actualSeriesList));

ここで要求されていることを正確に行うと主張するCollectionUtils.isEqualCollectionも見つけました...

https://commons.Apache.org/proper/commons-collections/apidocs/index.html?org/Apache/commons/collections4/CollectionUtils.html

9
Alex Worden

パーティーに遅刻しましたが、ここではJunitのみを使用したソリューションを紹介します。どんな考えでも大歓迎です。

List<String> actual = new ArrayList<>();
actual.add("A");
actual.add("A");
actual.add("B");

List<String> expected = new ArrayList<>();
actual.add("A");
actual.add("B");
actual.add("B");

//Step 1: assert for size
assertEquals(actual.size(), expected.size());

//Step 2: Iterate
for(String e: expected){
    assertTrue(actual.contains(e));
    actual.remove(e);
}
1
Sujit Joshi

Roberto Izquierdoによるソリューションは、一般に2次の複雑さを持っていることに注意してください。 HashSetsのソリューションには常に線形の複雑さがあります。

assertTrue(first.size() == second.size() &&
        new HashSet(first).equals(new HashSet(second)));
1
leventov

Junit-addons jarに含まれる ListAssert を使用できます。

ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5));
1
akungta
    Collections.sort(excepted);
    Collections.sort(actual);
    assertEquals(excepted,actual);
1
Tinyfool

簡単な修正のために、私は両方の方法をチェックします:

assertTrue(first.containsAll(second));
assertTrue(second.containsAll(first));

そして、同じ要素の数が異なる状況(1、1、2、1、2、2など)で試してみましたが、誤検出はありませんでした。

0

AssertJでは、containsExactlyInAnyOrder()またはcontainsExactlyInAnyOrderElementsOf()が必要です:

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import Java.util.Arrays;
import Java.util.List;

public class CompareListTest {

    @Test
    public void compareListWithTwoVariables() {
        List<String> expected = Arrays.asList("String A", "String B");
        List<String> actual = Arrays.asList("String B", "String A");
        Assertions.assertThat(actual)
                  .containsExactlyInAnyOrderElementsOf(expected);
    }

    @Test
    public void compareListWithInlineExpectedValues() {
        List<String> actual = Arrays.asList("String B", "String A");
        Assertions.assertThat(actual)
                  .containsExactlyInAnyOrder("String A", "String B");
    }    
}
0
davidxxx