2010-02-22 12 views
70

¿Cómo afirmaría sucintamente la igualdad de los elementos collections, específicamente un Set en JUnit 4?JUnit 4 comparar Colecciones

+2

cheque este SO enviar http://stackoverflow.com/questions/1086691/collectionassert-in-junit –

+0

¿Estás tratando de afirmar que dos conjuntos son iguales entre sí (contienen los mismos elementos) o que dos elementos del mismo conjunto son iguales? –

+0

Necesito ver que los elementos de dos conjuntos son iguales – Eqbal

Respuesta

74

Usted puede simplemente afirmar que los dos conjuntos son iguales entre sí, que invoca el Conjunto equals() method.

public class SimpleTest { 

    private Set<String> setA; 
    private Set<String> setB; 

    @Before 
    public void setUp() { 
     setA = new HashSet<String>(); 
     setA.add("Testing..."); 
     setB = new HashSet<String>(); 
     setB.add("Testing..."); 
    } 

    @Test 
    public void testEqualSets() { 
     assertEquals(setA, setB); 
    } 
} 

Esta prueba pasará si los dos conjuntos son del mismo tamaño y contienen los mismos elementos.

+2

También funciona para Map. –

+4

Esto no muestra muy buenos resultados en el informe. Si su toStrings está claramente definido, es mejor, pero aún así no es bueno (una pequeña diferencia puede terminar en una página de texto) –

+0

Uhm, cómo es que obtengo: java.lang.AssertionError: expected: java.util.Hashtable <{ NombreCompañía = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ, Ric = sZwmXAdYKv, Categoría = AvrIfd, QuoteID = 4342740204922826921}> pero era: java.util.Hashtable <{CompanyName = 8PKQ9va3nW8pRWb4SjPF2DvdQDBmlZ, Ric = sZwmXAdYKv, Categoría = AvrIfd, QuoteID = 4342740204922826921}> –

10

con hamcrest:

assertThat(s1, is(s2)); 

con afirmar claro:

assertEquals(s1, s2); 

NB: t los iguales() de la clase conjunto concreto se utiliza

+0

Prefiero este método ya que Hamcrest viene con JUnit 4 por lo que no hay necesidad de otras bibliotecas. – JRSofty

+1

Esto puede no funcionar cuando los conjuntos tienen diferentes tipos. –

2

Comprobar this article. Un ejemplo de allí:

@Test 
public void listEquality() { 
    List<Integer> expected = new ArrayList<Integer>(); 
    expected.add(5); 

    List<Integer> actual = new ArrayList<Integer>(); 
    actual.add(5); 

    assertEquals(expected, actual); 
} 
+0

Enlace corto pero excelente, explica muy rápido lo que puede hacer con Junit4- – Johannes

+0

El enlace está roto. ¿Alguna posibilidad de encontrar una versión archivada en línea o resumir sus contenidos? – pzp

6

Un caso particularmente interesante es cuando se compara

java.util.Arrays$ArrayList<[[name,value,type], [name1,value1,type1]]> 

y

java.util.Collections$UnmodifiableCollection<[[name,value,type], [name1,value1,type1]]> 

Hasta ahora, la única solución que veo es cambiar tanto de ellos en conjuntos

assertEquals(new HashSet<CustomAttribute>(customAttributes), new HashSet<CustomAttribute>(result.getCustomAttributes())); 

O podría compararlos elemento por elemento.

+0

En realidad, hay varias soluciones para las que se presentan en las otras respuestas. Los conjuntos son un poco desafortunados para esto, de todos modos, ya que ignoran el orden. Quizás ArrayList? –

29

Apache comunes para el rescate de nuevo.

assertTrue(CollectionUtils.isEqualCollection(coll1, coll2)); 

Funciona como un encanto. No sé por qué pero encontré que con las colecciones, el siguiente assertEquals(coll1, coll2) no siempre funciona. En el caso de que fallara, tenía dos colecciones respaldadas por Sets. Ni Hamcrest ni Junit dirían que las colecciones eran iguales, aunque sabía con certeza que lo eran. Usando CollectionUtils funciona perfectamente.

+14

Esto es realmente trivial, la parte difícil es indicar claramente la diferencia a la persona que llama –

+1

La respuesta aceptada es una buena respuesta para la pregunta original (prueba unitaria específicamente para dos conjuntos) pero esta respuesta con CollectionUtils es una mejor respuesta para el caso más general. No pude comparar una Colección y un Conjunto a menos que use CollectionUtils. – Jay

4

Como método adicional basado en matrices ... puede considerar el uso de aserciones de matrices no ordenadas en junitx. Aunque el ejemplo Apache CollectionUtils va a funcionar, hay un thepacakge de extensiones afirmación sólidas allí también:

creo que el enfoque

ArrayAssert.assertEquivalenceArrays(new Integer[]{1,2,3}, new Integer[]{1,3,2}); 

será mucho más fácil de leer y depurable para usted (Todas las colecciones apoyan toArray(), por lo tanto, debería ser bastante fácil utilizar los métodos ArrayAssert.

Por supuesto, la desventaja aquí es que junitx es un archivo jar adicional o una entrada de experto ...

<dependency org="junit-addons" name="junit-addons" rev="1.4"/> 
0

Si desea comprobar si una lista o grupo se compone de un conjunto de valores específicos (en lugar de compararlo con una colección ya existente), a menudo el método toString de las colecciones es útil:

String[] actualResult = calltestedmethod(); 
assertEquals("[foo, bar]", Arrays.asList(actualResult).toString()); 

List otherResult = callothertestedmethod(); 
assertEquals("[42, mice]", otherResult.toString()); 

Esto es un poco más corto que construir primero la colección esperada y compararla con la colección real, y más fácil de escribir y corregir.

(Es cierto que este no es un método particularmente limpio, y no se puede distinguir un elemento "foo, bar" de dos elementos "foo" y "bar". Pero en la práctica creo que es más importante que sea fácil y rápido para escribir pruebas, de lo contrario muchos desarrolladores simplemente no van sin ser presionado)

+0

Esto hace que el resultado de su prueba de unidad dependa de la implementación de toString de la lista. Si deciden cambiar el formato, la prueba unitaria ya no funcionará. No lo consideraría seguro. –

+0

@ LaurensOp'tZandt ¿Quiere decir que Oracle está cambiando el formato de Collection.toList()? Eso ciertamente no va a suceder. Sin embargo, tienes razón, eso no es particularmente limpio. Pero en la práctica, tengo la impresión de que es muy importante que sea muy fácil escribir pruebas. –

+0

Estoy de acuerdo, creo que el método toString no es probable. Entonces probablemente continuará funcionando. Solo quería señalar que no es una forma muy limpia. Pero de hecho es muy fácil. Un problema que surge es cuando se comparan conjuntos. Dado que su orden no está garantizada –

2

Usando Hamcrest:.

assertThat(set1, both(everyItem(isIn(set2))).and(containsInAnyOrder(set1))); 

Esto funciona también cuando los conjuntos tienen diferentes tipos de datos, e informa de la diferencia en lugar de sólo en su defecto .

+1

¿Cuál es la importación de isIn? IntelliJ no puede resolver la importación con ningún paquete de hamcret. – fabien

0

Me gusta la solución de Hans-Peter Störr ... Pero creo que no es del todo correcto. Tristemente containsInAnyOrder no acepta un Collection de objetos con los que comparar. Así que tiene que ser un Collection de Matcher s:

assertThat(set1, containsInAnyOrder(set2.stream().map(IsEqual::equalTo).collect(toList()))) 

La importación son:

import static java.util.stream.Collectors.toList; 
import static org.hamcrest.Matchers.containsInAnyOrder; 
import static org.junit.Assert.assertThat; 
Cuestiones relacionadas