2009-07-10 12 views
8

Ich versuche, die @Test (expected = RuntimeException.class) Annotation in Reihenfolge für eine erwartete Ausnahme zu testen. Mein Code ist wie folgt:Junit4: erwartet = Ausnahme funktioniert nicht mit SPRING

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

        User user = domain.save(null); 

    } 

und meine speichern Methode einfach wie folgt aus:

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

nach dem Debuggen von Code fand ich, dass Code werfen die Ausnahme wie erwartet, aber seine immer irgendwo dazwischen im Frühjahr gegessen Framework-Klassen.

habe ich versucht, das gleiche mit dem alten Weg (catch-Block versuchen), aber ich bin nicht in der Lage noch diese Ausnahme im Test zu fangen und Test hält Fehler in runafter Methode des Junit werfen:

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 

Und ich bin sicher, Das liegt daran, dass RuntimeException ich speichere, aber nicht in der Lage bin, es zu fangen oder den Test mit der erwarteten Klausel zu bestehen.

hat jemand eine idee, was schief geht?

+0

Wenn Frühling immer die Ausnahme fängt, warum wollen Sie dafür prüfen, es nicht zu tun? Ist das nicht das erwartete Verhalten (auch wenn nicht das, was * du * erwartet hast) –

+0

ja das ist wahr, aber es wirft Fehler auf der Konsole danach. Also ich will es selbst fangen. – ravinikam

Antwort

4

Hier ist eine Problemumgehung mit Junit 4.5 - trennen Sie die @Transactional und @ExpectedException in verschachtelte Funktionen. Ich denke, das Problem hat etwas mit dem AOP-Zeug zu tun, das sich um eine @Transactional-Methode dreht.

@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

Entweder Sie führen einen Komponententest aus, in diesem Fall sollte Spring TX nicht zum Spielen kommen, oder Sie führen eine Art Integrationstest aus, bei dem Sie testen möchten, was die Speichermethode bei der Laufzeitausnahme tut ist geschluckt. Ich denke nicht, dass irgendetwas schief läuft, du musst nur sicherstellen, dass du verstehst, was du versuchst zu testen.

+0

danke Paul, wenn du dir die Stack-Trace anschaust, mache ich Tests mit SpringJUnit4ClassRunner, also kommt Spring TX ins Spiel. Es funktioniert mit @NotTransactional Annotation. – ravinikam

+0

Nun, genau. Führen Sie es entweder mit plain old junit und nicht mit SpringJUnit4ClassRunner aus und testen Sie auf Laufzeitausnahme, oder testen Sie auf erwartetes Transaktionsverhalten. –

6

Es stellte sich heraus, dass meine erste Antwort falsch war. Sowohl @Test (erwartet = ...) als auch @ExpectedException funktionieren, aber es gibt eine Inkompatibilität zwischen the Spring TestContext and Junit 4.5. Die Verwendung von Junit 4.4 hat das Problem für mich gelöst. Endlich.

Verwandte Themen