Saltar al contenido

Mockito verificar después de la excepción Junit 4.10

Después de consultar especialistas en esta materia, programadores de deferentes ramas y maestros hemos dado con la solución al problema y la compartimos en esta publicación.

Solución:

ExpectedException funciona envolviendo todo su método de prueba en un bloque try-catch a través de JUnit @Rule. Cuando su código arroja una excepción, sube la pila hasta el intento/captura más cercano, que se encuentra en la instancia de ExpectedException (que verifica que es la excepción que está esperando).

En Java, si ocurre una excepción no detectada en un método, el control nunca volverá a las declaraciones posteriores en ese método. Las mismas reglas se aplican aquí: Control nunca regresa a las declaraciones en su prueba después de la excepción.

Técnicamente, podrías poner las verificaciones en un bloque finalmente, pero eso tiende a ser un mal hábito. EDITAR: Su sistema bajo prueba podría arrojar una excepción inesperada, o ninguna excepción, lo que le daría un mensaje de falla útil y un seguimiento; sin embargo, si esa falla hace que sus verificaciones o afirmaciones fallen en el finally bloque, Java lo mostrará en lugar de un mensaje sobre la excepción inesperada o el éxito inesperado. Esto puede dificultar la depuración, especialmente porque su error provendrá de líneas de código que siguen la causa raíz del error, lo que implica incorrectamente que el código anterior tuvo éxito.

Si realmente necesita verificar el estado después de la excepción, según el método, siempre puede volver a esta expresión:

@Test
public void testExpectedException()

  MockedObject mockObj = mock(MockedObj.class);
  MySubject subject = new MySubject(mockedObj);
  try 
    subject.someMethodThrowingException();
    fail("Expected MyException.");
   catch (MyException expected) 
    assertEquals("My exception message.", expected.getMessage());
  
  verify(mockObj).someCleanup(eq(...));

Actualizar: Con las expresiones lambda de Java 8, puede envolver una llamada de interfaz funcional en un bloque de prueba de manera lo suficientemente concisa como para ser útil. Me imagino que el soporte para esta sintaxis encontrará su camino en muchas bibliotecas de prueba estándar.

assertThrows(MyException.class,
    () -> systemUnderTest.throwingMethod());

Una vez que se lanza la excepción en UT, se ignorará todo el código a continuación.

@Test(expected = Exception.class)
public void testExpectedException() 
   MockedObject mockObj = mock(MockedObj.class);
   MySubject subject = new MySubject(mockedObj);
   subject.doSomething(); // If this line results in an exception then all the code below this will be ignored.
   subject.someMethodThrowingException();
   verify(mockObj).
       someCleanup(eq(...));

Para contrarrestar esto y verificar todas las llamadas realizadas, podemos usar tratar con por fin.

@Test(expected = Exception.class)
    public void testExpectedException() 
          MockedObject mockObj = mock(MockedObj.class);
          MySubject subject = new MySubject(mockedObj);
          try 
               subject.someMethodThrowingException(); 
           finally 
             verify(mockObj).
             someCleanup(eq(...));
          
 

Solución más elegante con excepción de captura

@Test
public void testExpectedException()

    MockedObject mockObj = mock(MockedObject.class);
    MySubject subject = new MySubject(mockObj);

    when(subject).someMethodThrowingException();

    then(caughtException())
            .isInstanceOf(MyException.class)
            .hasMessage("My exception message.");

    verify(mockObj).someCleanup(eq(...));

Recuerda algo, que tienes la capacidad de decir si te fue útil.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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