java - matchers - ¿Por qué debería usar Hamcrest-Matcher y assertThat() en lugar de los tradicionales assertXXX()-Methods
import static org hamcrest corematchers containsstring (7)
Básicamente para aumentar la legibilidad del código .
Además de hamcrest, también puedes usar las afirmaciones fest . Tienen algunas ventajas sobre el hamcrest, tales como:
- ellos son mas legibles
(assertEquals(123, actual); // reads "assert equals 123 is actual"
vs.
assertThat(actual).isEqualTo(123); // reads "assert that actual is equal to 123")
- son reconocibles ( puede hacer que el autocompletado funcione con cualquier IDE ).
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
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 )
.
Es agradable tal vez para los mensajes si los constructos se vuelven más complicados, pero ¿ves más ventajas? ¿Legibilidad?
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!
- puedes hacer tus pruebas más particulares
- obtienes una Excepción más detallada, si las pruebas fallan
- más fácil de leer la prueba
por cierto: también puedes escribir texto en assertXXX ...
Las notas de la versión JUnit para la versión 4.4 (donde se introdujo) establecen cuatro ventajas:
- Más legible y escribible: esta sintaxis le permite pensar en términos de sujeto, verbo, objeto (afirmar "x es 3") en lugar de assertEquals , que usa verbo, objeto, sujeto (afirmar "es igual a 3 x")
- Combinaciones: cualquier declaración de emparejador s puede ser negada ( no (s) ), combinada ( cualquiera (s) .o (t) ), mapeada a una colección ( cada (s) ), o utilizada en combinaciones personalizadas (después de cinco segundos) )
- Mensajes de falla legible (...)
- Matchers personalizados. Al implementar la interfaz de Matcher 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: here .
No hay una gran ventaja para aquellos casos en que exista una assertFoo
que coincida exactamente con su intención. En esos casos, se comportan casi igual.
Pero cuando se llega a controles que son algo más complejos, entonces la ventaja se vuelve más visible:
assertTrue(foo.contains("someValue") && foo.contains("anotherValue"));
vs.
assertThat(foo, hasItems("someValue", "anotherValue"));
Uno puede discutir cuál de ellos es más fácil de leer, pero una vez que falla la assertThat
, obtendrá un buen mensaje de error de assertThat
, pero solo una cantidad mínima de información de assertTrue
.
assertThat
le dirá qué fue la aseveración y qué obtuvo en su lugar. assertTrue
solo te dirá que tienes false
donde esperabas que fuera true
.
Una justificación muy básica es que es difícil estropear la nueva sintaxis.
Supongamos que un valor particular, foo, debe ser 1 después de una prueba.
assertEqual(1, foo);
--O--
assertThat(foo, is(1));
Con el primer enfoque, es muy fácil olvidar el orden correcto y escribirlo al revés. Entonces, en lugar de decir que la prueba falló porque esperaba 1 y obtuvo 2, el mensaje está al revés. No es un problema cuando pasa la prueba, pero puede generar confusión cuando la prueba falla.
Con la segunda versión, es casi imposible cometer este error.
hay ventajas para afirmar que sobre assertEquals -
1) más legible
2) más información sobre el fracaso
3) errores de tiempo de compilación, en lugar de errores de tiempo de ejecución
4) flexibilidad con condiciones de prueba de escritura
5) portátil: si usa hamcrest, puede usar jUnit o TestNG como marco subyacente.
assertThat(frodo.getName()).isEqualTo("Frodo");
Está cerca del lenguaje natural.
Lectura más fácil, código de análisis más fácil. 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.
El código de la PS debe ser tan bien escrito. Código auto documentado.