Creo que debería ser una pregunta realmente simple. Pero de alguna manera no puedo encontrar la respuesta en Google.
Suponga que tengo 2 listas de cadenas. Primero contiene "Cadena A" y "Cadena B" , el segundo contiene "Cadena B" y "Cadena A" (observe la diferencia en el orden). Quiero probarlos con JUnit para verificar si contienen exactamente las mismas cadenas.
¿Hay alguna afirmación que compruebe la igualdad de cadenas que ignoran el orden? Por ejemplo, org.junit.Assert.assertEquals arroja AssertionError
java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]>
La solución consiste en ordenar las listas en primer lugar y luego pasarlas a la afirmación. Pero quiero que mi código sea lo más simple y limpio posible.
Yo uso Hamcrest 1.3 , JUnit 4.11 , Mockito 1.9.5 .
list1.removeAll(list2)
debe dejarlist1
vacío. Supongo que puedes aprovechar esto para conseguir lo que quieres.containsAll
yremoveAll
sonO(n²)
para listas mientras las ordena y la prueba de igualdad esO(nlogn)
.Collections.sort(list1); Collections.sort(list2); assertTrue(list1.equals(list2));
también está limpio.Respuestas:
Como mencionas que usas Hamcrest, elegiría uno de los Matchers de la colección
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())); } }
fuente
Puede usar List.containsAll con JUnit's assertTrue para verificar que la primera lista contiene todos los elementos del segundo, y viceversa.
fuente
assertEquals(first.size(), second.size())
... entonces debería funcionar como se esperabaList<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));
En este ejemplo, ambas afirmaciones no detectan que las listas son realmente diferentes. @AlexWorden menciona CollectionUtils.isEqualCollection () de Apache Commons Collections que, para este ejemplo, detecta correctamente que las colecciones no son iguales.Aquí hay una solución que evita la complejidad cuadrática (iterar sobre las listas varias veces). Esto utiliza la clase CollectionUtils de Apache Commons para crear un mapa de cada elemento a un recuento de frecuencia en la lista. Luego, simplemente compara los dos mapas.
Assert.assertEquals("Verify same metrics series", CollectionUtils.getCardinalityMap(expectedSeriesList), CollectionUtils.getCardinalityMap(actualSeriesList));
También acabo de ver CollectionUtils.isEqualCollection que afirma hacer exactamente lo que se solicita aquí ...
https://commons.apache.org/proper/commons-collections/apidocs/index.html?org/apache/commons/collections4/CollectionUtils.html
fuente
Con AssertJ,
containsExactlyInAnyOrder()
ocontainsExactlyInAnyOrderElementsOf()
es lo que necesitas: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"); } }
fuente
fuente
Llego tarde a la fiesta, pero esta es mi solución usando solo Junit. Cualquier pensamiento es bienvenido.
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); }
fuente
Tenga en cuenta que la solución de Roberto Izquierdo tiene una complejidad cuadrática en general. La solución en HashSets siempre tiene una complejidad lineal:
assertTrue(first.size() == second.size() && new HashSet(first).equals(new HashSet(second)));
fuente
("s1", "s2", "s3" ,"s1")
y el segundo("s2", "s1", "s3" ,"s2");
no son la misma lista.Para una solución rápida, comprobaría en ambos sentidos:
Y al intentar con una situación en la que el número de los mismos elementos es diferente (por ejemplo, 1, 1, 2 y 1, 2, 2) no obtuve falsos positivos.
fuente
Puede usar ListAssert que viene en el jar junit-addons.
ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5));
fuente
Parece que las otras respuestas hacen referencia a utilidades de terceros, son incorrectas o ineficaces.
Aquí hay una solución básica O (N) en 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; }
fuente