Hay un proyecto del que me di cuenta después de crear esta respuesta que parece prometedor, es una excepción .
Como dice la descripción del proyecto, permitió que un codificador escribiera en una línea fluida de código para detectar la excepción y ofrecer esta excepción para la última afirmación. Y puede usar cualquier biblioteca de aserciones como Hamcrest o AssertJ .
Un ejemplo rápido tomado de la página de inicio:
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
when(myList).get(1);
// then: we expect an IndexOutOfBoundsException
then(caughtException())
.isInstanceOf(IndexOutOfBoundsException.class)
.hasMessage("Index: 1, Size: 0")
.hasNoCause();
Como puede ver, el código es realmente sencillo, detecta la excepción en una línea específica, la then
API es un alias que usará API AssertJ (similar a usar assertThat(ex).hasNoCause()...
). En algún momento, el proyecto se basó en FEST-Assert, el antepasado de AssertJ . EDITAR: Parece que el proyecto está gestando un soporte para Java 8 Lambdas.
Actualmente, esta biblioteca tiene dos deficiencias:
Al momento de escribir esto, es digno de mención decir que esta biblioteca se basa en Mockito 1.x ya que crea una simulación del objeto probado detrás de la escena. Como Mockito todavía no está actualizado, esta biblioteca no puede funcionar con clases finales o métodos finales . E incluso si se basara en Mockito 2 en la versión actual, esto requeriría declarar un creador de simulacros global ( inline-mock-maker
), algo que puede no ser lo que desea, ya que este simulador tiene diferentes inconvenientes que el creador de simulacros regular.
Requiere otra dependencia de prueba.
Estos problemas no se aplicarán una vez que la biblioteca admita lambdas. Sin embargo, la funcionalidad será duplicada por el conjunto de herramientas AssertJ.
Teniendo todo en cuenta si no desea utilizar la herramienta de captura de excepciones, recomendaré la antigua y buena forma del bloque try
- catch
, al menos hasta el JDK7. Y para los usuarios de JDK 8, es posible que prefiera usar AssertJ, ya que ofrece más que solo afirmar excepciones.
Con el JDK8, las lambdas entran en la escena de prueba, y han demostrado ser una forma interesante de afirmar un comportamiento excepcional. AssertJ se ha actualizado para proporcionar una API fluida y agradable para afirmar un comportamiento excepcional.
Y una prueba de muestra con AssertJ :
@Test
public void test_exception_approach_1() {
...
assertThatExceptionOfType(IOException.class)
.isThrownBy(() -> someBadIOOperation())
.withMessage("boom!");
}
@Test
public void test_exception_approach_2() {
...
assertThatThrownBy(() -> someBadIOOperation())
.isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
@Test
public void test_exception_approach_3() {
...
// when
Throwable thrown = catchThrowable(() -> someBadIOOperation());
// then
assertThat(thrown).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
Con una reescritura casi completa de JUnit 5, las afirmaciones se han mejorado un poco, pueden resultar interesantes como una forma inmediata de afirmar correctamente la excepción. Pero realmente la API de afirmación sigue siendo un poco pobre, no hay nada afuera assertThrows
.
@Test
@DisplayName("throws EmptyStackException when peeked")
void throwsExceptionWhenPeeked() {
Throwable t = assertThrows(EmptyStackException.class, () -> stack.peek());
Assertions.assertEquals("...", t.getMessage());
}
Como notaron, assertEquals
todavía está regresando void
, y como tal no permite encadenar afirmaciones como AssertJ.
Además, si recuerda el choque de nombres con Matcher
o Assert
, prepárese para enfrentar el mismo choque con Assertions
.
org.mockito.Mockito.verify
con varios parámetros para asegurarme de que ocurrieron ciertas cosas (de modo que se llamó a un servicio de registro con los parámetros correctos) antes de que se lanzara la excepción.