unitarias unitaria tutorial suma sintaxis pruebas prueba fail ejemplos configuracion con java exception junit

java - unitaria - Prueba JUnit-análisis de excepciones esperadas



pruebas unitarias (11)

Solución Java 8

Aquí hay una función de utilidad que escribí:

public final <T extends Throwable> T expectException( Class<T> exceptionClass, Runnable runnable ) { try { runnable.run(); } catch( Throwable throwable ) { if( throwable instanceof AssertionError && throwable.getCause() != null ) throwable = throwable.getCause(); //allows "assert x != null : new IllegalArgumentException();" assert exceptionClass.isInstance( throwable ) : throwable; //exception of the wrong kind was thrown. assert throwable.getClass() == exceptionClass : throwable; //exception thrown was a subclass, but not the exact class, expected. @SuppressWarnings( "unchecked" ) T result = (T)throwable; return result; } assert false; //expected exception was not thrown. return null; //to keep the compiler happy. }

( tomado de mi blog )

Úselo de la siguiente manera:

@Test public void testThrows() { RuntimeException e = expectException( RuntimeException.class, () -> { throw new RuntimeException( "fail!" ); } ); assert e.getMessage().equals( "fail!" ); }

Además, si desea leer algunas razones por las que no debería querer verificar el mensaje de su excepción, consulte esto: https://softwareengineering.stackexchange.com/a/278958/41811

Esta pregunta ya tiene una respuesta aquí:

En JUnit, actualmente estoy usando la anotación para esperar una excepción en mis pruebas.

¿Hay alguna forma de analizar esta excepción? Por ejemplo, espero una CriticalServerException , pero también quiero verificar el contenido del método getMessage .


Mire fluent-exception-rule , "combina la regla de Junit ExpectedException y las aserciones de AssertJ conveniencia".

import pl.wkr.fluentrule.api.FluentExpectedException; ... @Rule public FluentExpectedException thrown = FluentExpectedException.none(); @Test public void testDoSomethingCritical() { thrown.expect(CriticalServerException.class).hasMessage("Expected Message").hasNoCause(); obj.doSomethingCritical(); }


No creo que haya una forma de hacerlo usando la anotación. Es posible que deba retroceder para intentar capturar el camino donde en el bloque catch puede verificar el mensaje


No estoy seguro de si deberías. Usar un bloque try-catch para verificar el mensaje de error es tan junit3ish . Tenemos esta genial función ahora que puedes escribir @Test(expected=CriticalServerException.class) y quieres volver atrás y usar try-catch nuevamente para buscar una excepción que esperas, solo para verificar el mensaje de error.

OMI debe permanecer para la @Test(expected=CriticalServerException.class) e ignorar el mensaje de error. Revisar el mensaje de error, que se puede cambiar mucho ya que es una cadena más "legible por humanos" y no un valor técnico, también puede ser complicado. Está forzando a la excepción a tener un mensaje de error específico, pero es posible que no sepa quién generó la excepción y qué mensaje de error eligió.

En general, desea probar si el método arroja la excepción o no, y no cómo se ve el mensaje de error real. Si el mensaje de error es realmente tan importante, tal vez @Test(expected=...) considerar usar una subclase de la excepción que lanza y verificarla en @Test(expected=...) .


Si desea comparar el mensaje junto con el tipo de excepción, puede probar a continuación el fragmento de código.

@Rule public ExpectedException expectedException = ExpectedException.none(); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Parameter is not valid"); //check string contains expectedException.expectMessage(CoreMatchers.equalTo("Parameter is not valid")); //check string equals

Nota: Esto funcionará para junit 4.9 en adelante.


Si tiene JUnit 4.7 o superior, intente ExpectedException

Hay un ejemplo en esta pregunta , que se copia a continuación:

@Rule public ExpectedException exception = ExpectedException.none(); @Test public void testRodneCisloRok(){ exception.expect(IllegalArgumentException.class); exception.expectMessage("error1"); new RodneCislo("891415",dopocitej("891415")); }


Usar catch-exception :

catchException(obj).doSomethingCritical(); assertTrue(caughtException() instanceof CriticalServerException); assertEquals("Expected Message", caughtException().getMessage());


Utilice MethodRule como solución común, si tiene muchos casos de prueba para probar

public class ExceptionRule implements MethodRule { @Override public Statement apply(final Statement base, final FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { try { base.evaluate(); Assert.fail(); } catch (CriticalServerException e) { //Analyze the exception here } } }; } }

Luego usa la regla para tu clase de prueba:

@Rule public ExceptionRule rule = new ExceptionRule();


try { // your code fail("Didn''t throw expected exception"); } catch(CriticalServerException e) { assertEquals("Expected message", e.getMessage()); }


try { // test code invacation fail("Exception not throw!!!"); } catch(CriticalServerException ex) { assertTrue("Invalid exception data", ex.toString().contains("error text")); }


try{ //your code expecting to throw an exception fail("Failed to assert :No exception thrown"); } catch(CriticalServerException ex){ assertNotNull("Failed to assert", ex.getMessage()) assertEquals("Failed to assert", "Expected Message", ex.getMessage()); }