2009-07-10 4 views
8

Tôi đang cố sử dụng chú thích @Test (expected = RuntimeException.class) theo thứ tự để kiểm tra ngoại lệ dự kiến. Mã của tôi là như sau:Junit4: expected = Ngoại lệ không hoạt động với SPRING

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

        User user = domain.save(null); 

    } 

và tôi tiết kiệm phương pháp đơn giản như thế này:

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

sau khi gỡ lỗi mã tôi thấy rằng mã ném ngoại lệ như mong đợi nhưng nó bị ăn ở đâu đó ở giữa mùa xuân các lớp khung.

tôi đã cố gắng cùng với cách cũ (thử khối catch) nhưng tôi vẫn không thể bắt ngoại lệ mà trong thử nghiệm và kiểm tra giữ ném sai sót trong phương pháp runafter của 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 

Và tôi chắc chắn điều này là do RuntimeException mà tôi đang ném vào lưu nhưng không thể bắt nó hoặc vượt qua bài kiểm tra với mệnh đề dự kiến.

có ai biết điều gì đang xảy ra không?

+0

Nếu mùa xuân sẽ luôn bắt ngoại lệ, tại sao bạn muốn thử nghiệm nó không làm như vậy? Đây không phải là hành vi mong đợi (ngay cả khi không phải là những gì * bạn * đang mong đợi) –

+0

có thats true nhưng nó ném lỗi trên giao diện điều khiển sau đó. Vì vậy, tôi muốn bắt nó bản thân mình. – ravinikam

Trả lời

4

Đây là một công việc mà tôi đã tìm thấy với Junit 4.5 - tách biệt @Transactional và @ExpectedException thành các hàm lồng nhau. Tôi đoán vấn đề là một cái gì đó để làm với mùa xuân công cụ aop đặt xung quanh một phương pháp @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

Hoặc bạn đang chạy thử nghiệm đơn vị, trong trường hợp đó Spring TX không nên chạy hoặc bạn đang chạy thử nghiệm tích hợp nào đó mà bạn muốn kiểm tra phương pháp lưu nào khi ngoại lệ thời gian chạy của bạn bị nuốt phải. Tôi không nghĩ bất cứ điều gì là sai, bạn chỉ cần chắc chắn rằng bạn hiểu những gì nó là bạn đang cố gắng để kiểm tra.

+0

cảm ơn Paul, nếu bạn nhìn vào dấu vết ngăn xếp, tôi đang chạy thử nghiệm với SpringJUnit4ClassRunner, do đó, Spring TX đến chơi. Nó hoạt động với chú thích @NotTransactional. – ravinikam

+0

Vâng, chính xác. Hoặc chạy nó với junit cũ và không với SpringJUnit4ClassRunner và kiểm tra ngoại lệ thời gian chạy, hoặc kiểm tra hành vi giao dịch dự kiến. –

6

Hóa ra câu trả lời đầu tiên của tôi là sai. Cả @Test (expected = ...) và @ExpectedException đều hoạt động, nhưng có một số tính không tương thích giữa the Spring TestContext and Junit 4.5. Sử dụng Junit 4.4 giải quyết vấn đề cho tôi. Cuối cùng.