2009-07-10 13 views
8

Estoy tratando de usar la anotación @Test (expected = RuntimeException.class) en para probar una excepción esperada. Mi código es el siguiente:Junit4: expected = La excepción no funciona con SPRING

@Test(expected = RuntimeException.class) 
    public void testSaveThrowsRuntimeException(){ 

        User user = domain.save(null); 

    } 

y mi método save simple como esto:

public User save(User newUser) { 
     if(newUser == null) { 
      throw new RuntimeException(); 
     } 
     //saving code goes here 
    } 

después de depurar el código que encontró que el código de lanzar la excepción como se esperaba, pero su ser comido en algún punto intermedio en primavera clases de marco.

he intentado lo mismo con la vieja manera (trate bloque catch), pero todavía no soy capaz de atrapar esta excepción en la prueba y la prueba sigue echando errores en el método runafter de Junit:

org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException 
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1031) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678) 
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:504) 
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:277) 
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:170) 
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:344) 
at org.springframework.test.context.junit4.SpringMethodRoadie.runAfters(SpringMethodRoadie.java:307) 
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:338) 
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217) 
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197) 
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:142) 
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51) 
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44) 
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27) 
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37) 
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196) 
Caused by: javax.transaction.RollbackException 
at org.objectweb.jotm.TransactionImpl.commit(TransactionImpl.java:245) 
at org.objectweb.jotm.Current.commit(Current.java:488) 
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1028) 
... 23 more 

Y estoy seguro esto es debido a que RuntimeException estoy lanzando a guardar pero no puedo atraparlo o pasar la prueba con la cláusula esperada.

¿alguien tiene alguna idea de lo que está yendo mal?

+0

Si Spring siempre captará la excepción, ¿por qué quiere probar que no lo hace? ¿No es este el comportamiento esperado (incluso si no es lo que * usted * estaba esperando)? –

+0

sí, eso es cierto pero arroja un error en la consola después. Así que quiero atraparlo yo mismo. – ravinikam

Respuesta

4

He encontrado una solución alternativa con Junit 4.5: separe las funciones @Transactional y @ExpectedException en funciones anidadas. Supongo que el problema tiene algo que ver con el material de aop que la primavera pone alrededor de un método @Transactional.

@Test 
@ExpectedException(org.springframework.dao.DataIntegrityViolationException.class) 
public void Test10UniqueName() 
{ 
    DoTest10UniqueName(); 
} 

@Transactional 
public void DoTest10UniqueName() 
{ 
    final String NAME = "NAME"; 
    ProductCategoryDAO dao = DAOFactory.getProductCategoryDAO(); 
    ProductCategory test1 = new ProductCategory(); 
    test1.setName(NAME); 
    ProductCategory test2 = new ProductCategory(); 
    test2.setName(NAME); 
    dao.save(test1); 
    dao.save(test2); 
} 
1

Ya sea que esté ejecutando una prueba de unidad, en cuyo caso Spring TX no debería entrar para jugar, o está ejecutando algún tipo de prueba de integración donde quiere probar lo que hace el método de salvar cuando su excepción de tiempo de ejecución es ingerido. No creo que algo vaya mal, solo necesitas asegurarte de que comprendes qué es lo que estás tratando de probar.

+0

gracias Paul, si miras el rastro de la pila, estoy ejecutando pruebas con SpringJUnit4ClassRunner, por lo que Spring TX entra en juego. Funciona con la anotación @NotTransactional. – ravinikam

+0

Bueno, exactamente. Puede ejecutarlo con el antiguo junit normal y no con SpringJUnit4ClassRunner y probar la excepción de tiempo de ejecución o probar el comportamiento transaccional esperado. –

6

Resultó que mi primera respuesta fue incorrecta. Tanto @Test (expected = ...) como @ExpectedException funcionan, pero existe cierta incompatibilidad entre the Spring TestContext and Junit 4.5. El uso de Junit 4.4 me resolvió el problema. Finalmente.

Cuestiones relacionadas