web-dev-qa-db-de.com

AssertEquals 2 Listen ignorieren die Reihenfolge

Das sollte eine wirklich einfache Frage sein, glaube ich. Aber irgendwie finde ich keine Antwort in Google.

Angenommen, ich habe 2 Listen von Strings. Der erste enthält "String A" und "String B" , der zweite enthält "String B" und "String A" (Unterschied in der Reihenfolge beachten). Ich möchte sie mit JUnit testen, um zu prüfen, ob genau die gleichen Strings enthalten.

Gibt es eine Behauptung, die die Gleichheit von Strings überprüft, die die Reihenfolge ignorieren? Für gegebenes Beispiel löst org.junit.Assert.assertEquals AssertionError aus 

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

Umgehen Sie damit, die Listen zuerst zu sortieren und dann zur Bestätigung zu übergeben. Ich möchte jedoch, dass mein Code so einfach und sauber wie möglich ist.

Ich benutze Hamcrest 1.3 , JUnit 4.11 , Mockito 1.9.5 .

54
kukis

Da Sie erwähnen, dass Sie Hamcrest verwenden, würde ich eine der Matchers auswählen

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

}
54
cheffe

Sie können List.containsAll mit JUnits assertTrue verwenden, um zu prüfen, ob die erste Liste alle Elemente der zweiten enthält und umgekehrt.

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

Hier ist eine Lösung, die quadratische Komplexität vermeidet (mehrmaliges Durchlaufen der Listen). Hierbei wird die Klasse Apache Commons CollectionUtils verwendet, um eine Map von jedem Element mit einer Häufigkeit in der Liste selbst zu erstellen. Es vergleicht dann einfach die beiden Karten. 

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

Ich habe gerade auch CollectionUtils.isEqualCollection entdeckt, die behauptet, genau das zu tun, was hier angefordert wird ...

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

7
Alex Worden

Beachten Sie, dass die Lösung von Roberto Izquierdo im Allgemeinen eine quadratische Komplexität aufweist. Die Lösung für HashSets ist immer linear komplex:

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

Sie können ListAssert verwenden, das in junt-addons jar enthalten ist.

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

Ich bin spät dran, aber hier ist meine Lösung, die nur Junit verwendet. Irgendwelche Gedanken sind willkommen. 

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);
}
0
Sujit Joshi

Für eine schnelle Lösung würde ich beide Möglichkeiten prüfen:

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

Und ich versuche es mit einer Situation, in der die Anzahl der gleichen Elemente unterschiedlich ist (z. B. 1, 1, 2 und 1, 2, 2).

0

Mit AssertJ benötigen Sie containsExactlyInAnyOrder() oder 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