2009-07-10 7 views
8

Próbuję użyć adnotacji @Test (expected = RuntimeException.class) w , aby przetestować oczekiwany wyjątek. Mój kod wygląda następująco:Junit4: expected = Wyjątek nie działa z WIOSNĄ

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

        User user = domain.save(null); 

    } 

i mój Zapisz metoda prosta tak:

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

po debugowanie kodu znalazłem ten kod rzuca wyjątek, jak oczekiwano, ale jego coraz zjedzony gdzieś pomiędzy wiosną klasy szkieletowe.

próbowałem to samo z staremu (spróbuj blok catch), ale nadal nie jestem w stanie złapać ten wyjątek w teście i testy utrzymuje rzucanie błędy w sposobie runafter z 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 

I jestem pewien jest to spowodowane tym, że RuntimeException zapisuję, ale nie mogę go złapać lub zdać test z klauzulą ​​oczekiwaną.

ktoś ma pojęcie, co jest nie tak?

+0

Jeśli Spring zawsze będzie wychwytywał wyjątek, dlaczego chcesz go przetestować, nie robiąc tego? Czy nie jest to oczekiwane zachowanie (nawet jeśli nie tego * oczekiwałeś) –

+0

tak, to prawda, ale potem powoduje błąd na konsoli. Więc chcę go złapać. – ravinikam

Odpowiedz

4

Oto praca, którą udało mi się znaleźć dzięki Junit 4.5 - oddzielaj @Transactional i @ExpectedException od zagnieżdżonych funkcji. Domyślam się, że problem jest związany ze sprężyną materiałową aop, która skupia się na metodzie @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

Albo przeprowadzasz test jednostkowy, w którym to przypadku Spring TX nie powinien wchodzić w grę, albo masz jakiś test integracyjny, w którym chcesz przetestować, co robi metoda zapisu, gdy twój wyjątek środowiska wykonawczego jest połknięty. Nie sądzę, żeby coś poszło nie tak, po prostu upewnij się, że rozumiesz, co próbujesz przetestować.

+0

dziękuję Paul, jeśli spojrzysz na ślad stosu, testuję z SpringJUnit4ClassRunner, więc Spring TX wchodzi w grę. Działa z adnotacją @NotTransactional. – ravinikam

+0

No właśnie. Uruchom go na zwykłym starym junicie, a nie na SpringJUnit4ClassRunner i przetestuj wyjątek środowiska wykonawczego lub przetestuj oczekiwane zachowanie transakcyjne. –

6

Okazało się, że moja pierwsza odpowiedź była błędna. Zarówno @Test (expected = ...), jak i @ExpectedException działają, ale istnieje pewna niezgodność między the Spring TestContext and Junit 4.5. Użycie Junit 4.4 rozwiązało problem dla mnie. Wreszcie.