所以我有一個有趣的問題,我將需要一些幫助。我知道一些問題已經被問到使用junit進行事務回滾的問題,但我相信我的問題並且略有不同。爲了讓人們更好地理解這個問題,讓我從頭開始。Junit異常測試與春季交易和回滾
我已經爲用戶管理系統實施了用戶管理服務及其相應的DAO。有一種稱爲CreateUser(User obj)的通用方法,用於創建唯一用戶。現在,有一個約束條件,即電子郵件地址是唯一的,所以如果我們嘗試使用已經使用的電子郵件地址調用此方法,我們會拋出一個名爲UserManagementException的自定義異常及其相應的錯誤消息。所有這些工作都很好,但是我遇到的問題是單元測試。哦,差點忘了,讓我提我使用的軟件棧[的Java,spring,hibernate的]
我有我的單元測試類爲每個實際會達到分貝法事務的註解。這些方法還具有@Rollback註釋,以便在每次測試調用結束時回滾所有插入,更新和刪除操作。所以我在這裏面臨的問題是我想測試獨特的用戶約束場景。通過使用具有相同電子郵件地址的用戶對象第二次調用createUser(obj),我想確保拋出UserManagementException異常。但是,由於它是事務性的,所以無論何時拋出異常,事務在單元測試完成之前都會回滾,因此測試失敗。以下是測試用例。
@Test
@Rollback
@Transactional
public void testUniqueCreateConsoleUser() {
boolean success;
ConsoleUser newUser;
//first one
userManagementDao.createConsoleUser(user);
//second one. This shd throw a UserManagementException
try {
//now try and insert a new user with same email
newUser = new ConsoleUser("Queen", "Kong", "[email protected]", "kingkong","Universal Studios", "America/Los_Angeles", false, null);
userManagementDao.createConsoleUser(newUser);
//if this passed this is a problem. Console users should have unique email address
success = false;
} catch (UserManagementException e) {
success = true;
}
Assert.assertTrue(success);
}
奇怪的是,當我通過調試運行它,在Assert.assertTrue()方法調用正確的,但最終的測試失敗。
我嘗試的另一件事是添加一個道具到@Transactional註釋。我添加了流動的@Transactional(noRollbackFor = UserManagementException.class),希望如果拋出異常,那麼回滾將不會被調用,而是在測試結束時調用。我可能會以錯誤的方式來處理這個問題,所以圍繞這種測試的任何想法或最佳實踐都會受到極大的指導。
注:下面是從堆棧跟蹤片斷..
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:695)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$afterReturning$org_springframework_transaction_aspectj_AbstractTransactionAspect
是的,你說得對,我正在使用實際的DAO impl,因爲我想看到它在行動。我曾考慮過使用模擬對象,但我改變了主意,以使用實際的impl代替。 – 2011-12-23 20:05:59
我決定使用模擬對象方法。即使所有的答案都是有效的,我只能接受一個:-) – 2011-12-24 08:52:43