¿Por qué debo usar Hamcrest-Matcher y afirmar que () en lugar de los métodos tradicionales de afirmación XXX ()?

5 minutos de lectura

Cuando miro los ejemplos en la clase Assert JavaDoc

assertThat("Help! Integers don't work", 0, is(1)); // fails:
// failure message:
// Help! Integers don't work
// expected: is <1> 
// got value: <0>
assertThat("Zero is one", 0, is(not(1))) // passes

No veo una gran ventaja sobre, digamos, assertEquals( 0, 1 ).

Tal vez sea bueno para los mensajes si las construcciones se vuelven más complicadas, pero ¿ves más ventajas? ¿Legibilidad?

avatar de usuario
Joaquín Sauer

No hay gran ventaja para aquellos casos en los que un assertFoo existe que coincide exactamente con su intención. En esos casos se comportan casi igual.

Pero cuando se trata de controles que son un poco más complejos, la ventaja se vuelve más visible:

val foo = List.of("someValue");
assertTrue(foo.contains("someValue") && foo.contains("anotherValue"));
Expected: is <true>
         but: was <false>

contra

val foo = List.of("someValue");
assertThat(foo, containsInAnyOrder("someValue", "anotherValue"));
Expected: iterable with items ["someValue", "anotherValue"] in any order
     but: no item matches: "anotherValue" in ["someValue"]

Uno puede discutir cuál de ellos es más fácil de leer, pero una vez que falla la afirmación, recibirá un buen mensaje de error de assertThatpero sólo una cantidad mínima de información de assertTrue.

  • Yo también tenía esta pregunta en el fondo de mi mente. Gracias, nunca lo había pensado de esta manera.

    – trigo

    9 de noviembre de 2009 a las 14:06

  • También ayuda con la “regla” de una afirmación por prueba y se combina más fácilmente con las especificaciones de estilo BDD.

    – Nils Wloka

    20 de noviembre de 2009 a las 14:10

  • Y separa el mecanismo de aserción de la condición (que es lo que conduce a mejores mensajes de error).

    – SteveD

    30 de agosto de 2010 a las 8:46

  • El ejemplo es inverosímil ya que casi nadie usaría un solo assertTrue con un &&. Separarlo en dos condiciones hace que la causa del problema sea obvia incluso en JUnit. No me malinterpreten; Estoy de acuerdo contigo, simplemente no me gusta tu ejemplo.

    – maaartinus

    11 de agosto de 2017 a las 5:07

La JUnit Notas de lanzamiento para la versión 4.4 (donde se introdujo) indique cuatro ventajas:

  • Más legible y tipeable: esta sintaxis le permite pensar en términos de sujeto, verbo, objeto (afirmar “x es 3”) en lugar de afirmarIgualque usa verbo, objeto, sujeto (afirmar “es igual a 3 x”)
  • Combinaciones: cualquier declaración de comparación s puede ser negada (no(s)), combinado (ya sea(s).o
  • Mensajes de error legibles. (…)
  • Emparejadores personalizados. Al implementar el emparejador usted mismo, puede obtener todos los beneficios anteriores para sus propias afirmaciones personalizadas.

Argumentación más detallada del tipo que creó la nueva sintaxis: aquí.

avatar de usuario
Ígor Popov

Básicamente para aumentar la legibilidad del código.

Además del hamcrest también puede utilizar el afirmaciones festivas. Ellos tienen Algunas ventajas sobre Hamcrest como:

Algunos ejemplos

import static org.fest.assertions.api.Assertions.*;

// common assertions
assertThat(yoda).isInstanceOf(Jedi.class);
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);
assertThat(frodo).isIn(fellowshipOfTheRing);
assertThat(sauron).isNotIn(fellowshipOfTheRing);

// String specific assertions
assertThat(frodo.getName()).startsWith("Fro").endsWith("do")
                           .isEqualToIgnoringCase("frodo");

// collection specific assertions
assertThat(fellowshipOfTheRing).hasSize(9)
                               .contains(frodo, sam)
                               .excludes(sauron);


// map specific assertions (One ring and elves ring bearers initialized before)
assertThat(ringBearers).hasSize(4)
                       .includes(entry(Ring.oneRing, frodo), entry(Ring.nenya, galadriel))
                       .excludes(entry(Ring.oneRing, aragorn));

17 de octubre de 2016 Actualización

Fest ya no está activo, use AfirmarJ en cambio.

  • Fest parece haber muerto, pero la bifurcación AssertJ está muy viva.

    – Amédée Van Gasse

    17 de febrero de 2016 a las 11:11

avatar de usuario
martinl

Ejemplo:

assertThat(5 , allOf(greaterThan(1),lessThan(3)));
//  java.lang.AssertionError:
//  Expected: (a value greater than <1> and a value less than <3>)
//       got: <5>
assertTrue("Number not between 1 and 3!", 1 < 5 && 5 < 3);
//  java.lang.AssertionError: Number not between 1 and 3!
  1. puedes hacer tus pruebas más particulares
  2. obtiene una excepción más detallada, si las pruebas fallan
  3. más fácil de leer la prueba

por cierto: también puedes escribir Texto en assertXXX…

  • … y cuando Eclipse informa de un error de aserción, si coloca los argumentos al revés en la afirmación tradicional(), el error no tiene sentido.

    – Sridhar Sarnobat

    14/04/2016 a las 20:32

avatar de usuario
usuario4515828

assertThat(frodo.getName()).isEqualTo("Frodo");

Está cerca del lenguaje natural.

Código más fácil de leer, más fácil de analizar. El programador dedica más tiempo a analizar el código que a escribir uno nuevo. Entonces, si el código será fácil de analizar, entonces el desarrollador debería ser más productivo.

PS Code debería ser un libro tan bien escrito. Código autodocumentado.

  • Vale y…? Recomiendo apoyar su argumento explicando por qué eso es algo bueno.

    -Nathan Tuggy

    1 de febrero de 2015 a las 0:08

avatar de usuario
samshers

hay ventajas para afirmar Eso sobre afirmar Iguales –
1) más legible
2) más información sobre fallas
3) errores de tiempo de compilación, en lugar de errores de tiempo de ejecución
4) flexibilidad con las condiciones de prueba de escritura
5) portátil: si usa Hamcrest, puede usar jUnit o TestNG como marco subyacente.

  • Vale y…? Recomiendo apoyar su argumento explicando por qué eso es algo bueno.

    -Nathan Tuggy

    1 de febrero de 2015 a las 0:08

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad