Afirmación de excepción lanzada en Java

Afirmación de excepción lanzada en Java

En este artículo, vamos a aprender cómo afirmar excepciones lanzadas en Java utilizando las bibliotecas de afirmación JUnit 5 y AssertJ.

Índice
  1. Conocimiento
  2. Afirmar excepción lanzada
    1. Junit 5 - AfirmarLanzamientos
    2. AssertJ - afirmar esa excepción de tipo

Conocimiento

Por lo general, escribimos una prueba unitaria para verificar el resultado esperado de una pieza de código. También esperamos que este fragmento de código pueda generar una excepción en algunas situaciones y también queremos cubrir esos casos en nuestra prueba unitaria.

Es una buena práctica cubrir todas las excepciones que debe generar el código. Veamos cómo afirmar excepciones lanzadas usando JUnit 5 y AssertJ.

Afirmar excepción lanzada

Digamos que tenemos un método doStuff en la clase FooService. Este método puede arrojar un Excepción de puntero nulo cuando un No flag se pasa en el argumento.

public class FooService {

  public void doStuff(Boolean flag) {
    try{
      if(flag){
        // do stuff
      }
    }catch (Exception e){
      throw new RuntimeException("Unexpected error occurred", e);
    }
  }

  public void doOtherStuff() {
    // do other stuff
  }
}

Junit 5 - AfirmarLanzamientos

En Junit 5 podemos probar esto: -

  1. una excepción de un tipo específico es esperado ser lanzado por el código usando assertThrows() afirmación.
  2. una excepción es no esperado ser lanzado por el código usando assertDoesNotThrow() afirmación.
assertThrows(ExpectedException.class, () -> methodCall)
assertDoesNotThrow(() -> methodCall)

Veamos el ejemplo de usar assertThrows Y assertDoesNotThrow:-

import static org.junit.jupiter.api.Assertions.*;

FooService fooService = new FooService();

@Test
public void doStuff_testThrownException(){   
    // null is passed, expected NullPointerException
    Throwable exception = assertThrows(RuntimeException.class, () -> fooService.doStuff(null)); 

    assertEquals("Unexpected error occurred", exception.getMessage());
    assertEquals(NullPointerException.class, exception.getCause().getClass());
}

@Test
public void doStuff_shouldNotThrowException(){
  // method is expected to work fine without exception
  assertDoesNotThrow(() -> fooService.doStuff(true));
} 

Veamos algunos ejemplos de uso: -

// Assert IllegalArgumentException
assertThrows(IllegalArgumentException.class, () -> Integer.valueOf("foo"));

// Assert IndexOutOfBoundsException
Exception e = assertThrows(IndexOutOfBoundsException.class, () -> Arrays.asList("foo", "bar").get(2));
assertEquals("Index 2 out of bounds for length 2", e.getMessage());

// Assert RuntimeException
String str = null;
assertThrows(RuntimeException.class, () -> str.equals("foo"));

// Assert NullPointerException - exact match
assertThrowsExactly(NullPointerException.class, () -> str.equals("foo"));

AssertJ - afirmar esa excepción de tipo

En AssertJ podemos probar esto: -

  1. cualquier tipo de excepción Este esperado ser lanzado por el código usando assertThatThrownBy() afirmación.
  2. un tipo específico de excepción Este esperado ser lanzado por el código usando assertThatExceptionOfType() afirmación.
  3. una excepción es no esperado ser lanzado por el código usando assertThatNoException() afirmación.
assertThatThrownBy(() -> methodCall)
assertThatExceptionOfType(ExpectedException.class).isThrownBy(() -> methodCall)
assertThatNoException().isThrownBy(() -> methodCall)

Veamos el ejemplo de uso: -

import static org.assertj.core.api.Assertions.*;

FooService fooService = new FooService();

@Test
public void doStuff_testThrownException(){
  // null is passed, expected NullPointerException

  // example 1: assert for any exception
  assertThatThrownBy(() -> fooService.doStuff(null))
          .isInstanceOf(RuntimeException.class)
          .hasMessage("Unexpected error occurred")
          .hasCauseInstanceOf(NullPointerException.class);

  // example 2: assert for exception of type RuntimeException 
  assertThatExceptionOfType(RuntimeException.class)
          .isThrownBy(() -> fooService.doStuff(null))
          .withMessage("Unexpected error occurred")
          .withCauseInstanceOf(NullPointerException.class);

  // example 3: shortcut assert for RuntimeException
  assertThatRuntimeException().isThrownBy(() -> fooService.doStuff(null))
          .withMessage("Unexpected error occurred")
          .withCauseInstanceOf(NullPointerException.class);
}

@Test
public void doStuff_shouldNotThrowException(){
  // method is expected to work fine without exception
  assertThatNoException().isThrownBy(() -> fooService.doStuff(true));
}

Podemos usar cualquier afirmación entre assertThatThrownBy, assertThatExceptionOfTypeY assertThatRuntimeException para probar RuntimeException, este último es más legible.

Aserciones de acceso directo

AssertJ viene con aserciones de acceso directo para excepciones populares, p. IndexOutOfBoundsExceptionIndexOutOfBoundsException, Argumento de excepción ilegalY Excepción de puntero nulo. Veámoslos: -

@Test
public void testSomeMoreThrownException() {
  assertThatIndexOutOfBoundsException().isThrownBy(() -> Arrays.asList("foo", "bar").get(2))
          .withMessage("Index 2 out of bounds for length 2");

  assertThatIllegalArgumentException().isThrownBy(() -> Integer.valueOf("foo"))
          .isInstanceOf(NumberFormatException.class);

  assertThatNullPointerException().isThrownBy(() -> {
    String text = null;
    text.equals("foo");
  });
}

Si quieres conocer otros artículos parecidos a Afirmación de excepción lanzada en Java puedes visitar la categoría Tutoriales.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Esta página web utiliza cookies para analizar de forma anónima y estadística el uso que haces de la web, mejorar los contenidos y tu experiencia de navegación. Para más información accede a la Política de Cookies . Ver mas