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 .
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()));
}
}
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));
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 ...
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)));
Sie können ListAssert verwenden, das in junt-addons jar enthalten ist.
ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5));
Collections.sort(excepted);
Collections.sort(actual);
assertEquals(excepted,actual);
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);
}
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).
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");
}
}