Das sollte eine wirklich einfache Frage sein, glaube ich. Aber irgendwie kann ich in Google keine Antwort finden.
Angenommen, ich habe 2 Listen mit Zeichenfolgen. Der erste enthält "String A" und "String B" , der zweite "String B" und "String A" (Unterschied in der Reihenfolge beachten). Ich möchte sie mit JUnit testen, um zu überprüfen, ob sie genau die gleichen Strings enthalten.
Gibt es eine Behauptung, die die Gleichheit von Strings überprüft, die die Reihenfolge ignorieren? Für das angegebene Beispiel löst org.junit.Assert.assertEquals AssertionError aus
java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]>
Um dies zu umgehen, müssen zuerst die Listen sortiert und dann an die Zusicherung übergeben werden. Aber ich möchte, dass mein Code so einfach und sauber wie möglich ist.
Ich benutze Hamcrest 1.3 , JUnit 4.11 , Mockito 1.9.5 .
list1.removeAll(list2)
solltelist1
leer lassen. Ich denke, Sie können darauf aufbauen, um das zu bekommen, was Sie wollen.containsAll
undremoveAll
sindO(n²)
für Listen beim Sortieren und Testen auf Gleichheit istO(nlogn)
.Collections.sort(list1); Collections.sort(list2); assertTrue(list1.equals(list2));
ist auch sauber.Antworten:
Wenn Sie erwähnen, dass Sie Hamcrest verwenden, würde ich einen der Matcher der Sammlung 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())); } }
quelle
Sie können List.containsAll mit assertTrue von JUnit verwenden, um zu überprüfen, ob die erste Liste alle Elemente der zweiten enthält und umgekehrt.
quelle
assertEquals(first.size(), second.size())
..dann sollte es wie erwartet funktionierenList<String> list1 = Arrays.asList("a", "a", "b");
List<String> list2 = Arrays.asList("a", "b", "b");
assertEquals(list1.size(), list2.size());
assertTrue(list1.containsAll(list2) && list2.containsAll(list1));
In diesem Beispiel erkennen beide Zusicherungen nicht, dass die Listen tatsächlich unterschiedlich sind. @AlexWorden erwähnt die CollectionUtils.isEqualCollection () von Apache Commons Collections, die in diesem Beispiel korrekt erkennt, dass die Sammlungen nicht gleich sind.Hier ist eine Lösung, die quadratische Komplexität vermeidet (mehrmaliges Durchlaufen der Listen). Hierbei wird die Apache Commons CollectionUtils-Klasse verwendet, um eine Zuordnung jedes Elements zu einer Häufigkeit selbst in der Liste zu erstellen. Anschließend werden einfach die beiden Karten verglichen.
Assert.assertEquals("Verify same metrics series", CollectionUtils.getCardinalityMap(expectedSeriesList), CollectionUtils.getCardinalityMap(actualSeriesList));
Ich habe auch gerade 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/commons/collections4/CollectionUtils.html
quelle
Mit AssertJ
containsExactlyInAnyOrder()
odercontainsExactlyInAnyOrderElementsOf()
ist das, was Sie brauchen: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"); } }
quelle
quelle
Ich bin zu spät zur Party, aber hier ist meine Lösung nur mit Junit. Alle 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); }
quelle
Beachten Sie, dass die Lösung von Roberto Izquierdo im Allgemeinen eine quadratische Komplexität aufweist. Die Lösung auf HashSets ist immer linear komplex:
assertTrue(first.size() == second.size() && new HashSet(first).equals(new HashSet(second)));
quelle
("s1", "s2", "s3" ,"s1")
und zweitens ist("s2", "s1", "s3" ,"s2");
, sind sie nicht dieselbe Liste.Für eine schnelle Lösung würde ich beide Möglichkeiten prüfen:
Und wenn ich es mit einer Situation versuche, in der die Anzahl der gleichen Elemente unterschiedlich ist (z. B. 1, 1, 2 und 1, 2, 2), habe ich keine falsch positiven Ergebnisse erhalten.
quelle
Sie können ListAssert verwenden , das im Junit-Addons-Jar enthalten ist.
ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5));
quelle
Die anderen Antworten beziehen sich entweder auf Dienstprogramme von Drittanbietern, sind falsch oder ineffizient.
Hier ist eine O (N) Vanille-Lösung in Java 8.
public static void assertContainsSame(Collection<?> expected, Collection<?> actual) { assert expected.size() == actual.size(); Map<Object, Long> counts = expected.stream() .collect(Collectors.groupingBy( item -> item, Collectors.counting())); for (Object item : actual) assert counts.merge(item, -1L, Long::sum) != -1L; }
quelle