java unit-testing junit assertj

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?



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 con overridingErrorMessage(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.