java - assertj maven
¿Se puede agregar un mensaje personalizado a AssertJ afirmar eso? (3)
Tenemos un conjunto de pruebas que utiliza principalmente aserciones JUnit con los emparejadores Hamcrest. Uno de nuestro equipo comenzó a experimentar con AssertJ e impresionó a las personas con su sintaxis, flexibilidad y declaración. Hay una característica que JUnit proporciona para la que no puedo encontrar un equivalente en AssertJ: agregar un mensaje de falla de afirmación personalizado.
A menudo estamos comparando objetos que no están hechos para la legibilidad humana y que tendrán Ids o UUID de apariencia aleatoria y es imposible saber qué se supone que son por los datos que contienen. Esta es una situación inevitable para nuestra base de código, lamentablemente, como parte del propósito que cumple es mapear datos entre otros servicios sin necesariamente comprender lo que es.
En JUnit, el método
assertThat
proporciona una versión con un parámetro de
String reason
antes del parámetro
Matcher<T>
.
Esto hace que sea trivial agregar una cadena de depuración corta que arroje algo de luz sobre el problema, como lo que la comparación debería significar para un humano.
AssertJ, por otro lado, proporciona un millón de
static assertThat
genéricas
diferentes que devuelven algún tipo de
interfaz Assert
o una de sus muchas clases de implementación.
Esta interfaz no proporciona una forma estándar de configurar un mensaje personalizado para que se incluya con fallas.
¿Hay alguna forma de obtener esta funcionalidad de la API AssertJ o una de sus extensiones sin tener que crear una clase de afirmación personalizada para cada tipo de afirmación a la que queremos agregar mensajes?
Para su información, esto está documentado en el nuevo sitio web de AssertJ (que todavía está en construcción pero ya tiene información útil), consulte https://assertj.github.io/doc/#assertj-core-assertion-description .
Y de manera clásica, encontré lo que estaba buscando momentos después de publicar la pregunta.
Con suerte, esto facilitará la búsqueda de la siguiente persona sin tener que saber cómo se llama.
El método mágico es el nombre engañosamente corto
as
, que es parte de otra interfaz que implementa
AbstractAssert
:
Descriptable
, no la interfaz Assert base.
public S as(String description, Object... args)
Establece la descripción de este objeto que admite la
String.format(String, Object...)
.
Ejemplo:
try { // set a bad age to Mr Frodo which is really 33 years old. frodo.setAge(50); // you can specify a test description with as() method or describedAs(), it supports String format args assertThat(frodo.getAge()).as("check %s''s age", frodo.getName()).isEqualTo(33); } catch (AssertionError e) { assertThat(e).hasMessage("[check Frodo''s age] expected:<[33]> but was:<[50]>"); }
Donde esa cadena citada en el bloque catch
hasMessage
es lo que aparece en el registro de salida de prueba de la unidad si falla la aserción.
Encontré esto al notar el asistente
failWithMessage
en la
página de
failWithMessage
personalizada
vinculada en la pregunta.
El
JavaDoc
para ese método señala que está protegido, por lo que las personas que llaman no pueden usarlo para establecer un mensaje personalizado.
Sin embargo, menciona el
as
ayudante:
Además, este método respeta cualquier descripción establecida con
as(String, Object...)
o mensaje de error anulado definido por el usuario conoverridingErrorMessage(String, Object...)
.
... y el ayudante overridingErrorMessage, que reemplaza por completo el estándar AssertJ
expected: ... but was:...
mensaje con la nueva cadena proporcionada.
La página de inicio de AssertJ no menciona ninguno de los ayudantes hasta que la página de características destacadas, que muestra ejemplos de
as
ayudante en la sección
Afirmaciones suaves
, pero no describe directamente lo que hace.
Para agregar otra opción a la respuesta de Patrick M:
En lugar de usar
Descriptable.as
, también puede usar
AbstractAssert.withFailMessage()
:
try {
// set a bad age to Mr Frodo which is really 33 years old.
frodo.setAge(50);
// you can specify a test description via withFailMessage(), supports String format args
assertThat(frodo.getAge()).
withFailMessage("Frodo''s age is wrong: %s years, difference %s years",
frodo.getAge(), frodo.getAge()-33).
isEqualTo(33);
} catch (AssertionError e) {
assertThat(e).hasMessage("Frodo''s age is wrong: 50 years, difference 17 years");
}
La diferencia con el uso de
Descriptable.as
es que le da
un control completo sobre el mensaje personalizado
: no hay "esperado" y "pero fue".
Esto es útil cuando los valores reales que se prueban no son útiles para la presentación; este método le permite mostrar otros valores, posiblemente calculados, o ninguno en absoluto.
Tenga en cuenta que, al igual que
Descriptable.as
, debe llamar
withFailMessage()
antes de
cualquier afirmación real; de lo contrario, no funcionará, ya que la afirmación se activará primero.
Esto se observa en el Javadoc.