CollectionAssert en jUnit?

Respuestas:

125

Al usar JUnit 4.4, puede usarlo assertThat()junto con el código Hamcrest (no se preocupe, se envía con JUnit, no es necesario un extra .jar) para producir afirmaciones complejas de autodescripción, incluidas las que operan en colecciones:

import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.*;
import static org.hamcrest.CoreMatchers.*;

List<String> l = Arrays.asList("foo", "bar");
assertThat(l, hasItems("foo", "bar"));
assertThat(l, not(hasItem((String) null)));
assertThat(l, not(hasItems("bar", "quux")));
// check if two objects are equal with assertThat()

// the following three lines of code check the same thing.
// the first one is the "traditional" approach,
// the second one is the succinct version and the third one the verbose one 
assertEquals(l, Arrays.asList("foo", "bar")));
assertThat(l, is(Arrays.asList("foo", "bar")));
assertThat(l, is(equalTo(Arrays.asList("foo", "bar"))));

Con este enfoque, obtendrá automáticamente una buena descripción de la aserción cuando falle.

Joachim Sauer
fuente
1
Oh, no me había dado cuenta de que Hamcrest había llegado a la distribución junit. ¡Vamos, Nat!
skaffman
Si quiero afirmar que l está compuesto de elementos ("foo", "bar"), pero no existen otros elementos, ¿hay alguna sintaxis fácil para eso?
ripper234
Usa el fragmento de código anterior y tirar en un assertTrue adicional (l.size () == 2)
aberrant80
4
Meh, feo. En NUnit eso es CollectionAssert.AreEqual (Colección esperada, Colección real);
ripper234
1
¡Google ha encontrado otra respuesta de Stackoverflow que estaba buscando!
Mykola Golubyev
4

No directamente, no. Sugiero el uso de Hamcrest , que proporciona un rico conjunto de reglas de coincidencia que se integra muy bien con jUnit (y otros marcos de prueba)

skaffman
fuente
Esto no se compila por alguna razón (consulte stackoverflow.com/questions/1092981/hamcrests-hasitems ): ArrayList <Integer> actual = new ArrayList <Integer> (); ArrayList <Integer> esperado = new ArrayList <Integer> (); actual.add (1); esperado.add (2); assertThat (actual, hasItems (esperado));
ripper234
2

Eche un vistazo a FEST Fluent Assertions. En mi humilde opinión, son más convenientes de usar que Hamcrest (e igualmente potentes, extensibles, etc.) y tienen un mejor soporte IDE gracias a una interfaz fluida. Ver https://github.com/alexruiz/fest-assert-2.x/wiki/Using-fest-assertions

Tomek Kaczanowski
fuente
En 2017, parece que más personas están usando una rama de FEST llamada AssertJ.
Max
2

La solución de Joachim Sauer es buena, pero no funciona si ya tiene una serie de expectativas que desea verificar en su resultado. Esto puede surgir cuando ya tiene una expectativa generada o constante en sus pruebas con la que desea comparar un resultado, o tal vez tiene múltiples expectativas que espera fusionar en el resultado. Entonces, en lugar de usar emparejadores, puede usar List::containsAlly, assertTruepor ejemplo:

@Test
public void testMerge() {
    final List<String> expected1 = ImmutableList.of("a", "b", "c");
    final List<String> expected2 = ImmutableList.of("x", "y", "z");
    final List<String> result = someMethodToTest(); 

    assertThat(result, hasItems(expected1)); // COMPILE ERROR; DOES NOT WORK
    assertThat(result, hasItems(expected2)); // COMPILE ERROR; DOES NOT WORK

    assertTrue(result.containsAll(expected1));  // works~ but has less fancy
    assertTrue(result.containsAll(expected2));  // works~ but has less fancy
}
gavs
fuente
Siempre puedes usar hasItems(expected1.toArray(new String[expected1.size()])). Le dará mejores mensajes de error.
meustrus