簡體   English   中英

與其他啟用了事務的集成測試一起運行時,集成測試失敗

[英]An integration test fails when running with other integration tests which have transactional enabled

我遇到了一個測試多個服務的集成測試的問題。 我不得不禁用事務以使測試工作而沒有任何與事務相關的運行時錯誤。 集成測試在單獨運行時工作正常但在與其他啟用了事務的測試一起運行時,會產生此運行時錯誤:

Running 48 integration tests... 43 of 48
Failure:  Tests the happy case flow of MyService.(MyServiceSpec)
org.springframework.transaction.HeuristicCompletionException: Heuristic completion: outcome state is rolled back; nested exception is org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has bee
n marked as rollback-only
Caused by: org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
        ... 4 more
Completed 43 integration tests, 1 failed in 0m 32s

我得出結論,運行時發生的原因是因為使用事務的其他集成測試,因為我通過成功運行所有禁用事務的測試來測試它; 在使用事務啟用的單個集成測試運行測試時失敗。

如何在Grails中混合事務和非事務集成測試?

平台詳情:

Grails-2.3.6 Windows 7 64位。 JDK v6。

使用Grails 2.4.3進入這個並且在一堆調試之后看到org.springframework.orm.hiberante4.HibernateTransactionManager.doGetTransaction()它調用TransactionSynchronizationManager.getResource(getSessionFactory())並且如果有其他測試啟用了事務,那么它會找到一個線程綁定的SessionHolder,其rollbackOnly設置為true(因為之前的測試已回滾)。 因此,第一次嘗試提交事務時,它會看到這個並給出你指出的UnexpectedRollbackException

通過將以下內容放在標記為非事務性的測試的setUp()中,我解決了這個問題:

Holders.grailsApplication.mainContext.getBeansOfType(SessionFactory.class).each { beanName, sessionFactory ->

    SessionHolder sessionHolder = TransactionSynchronizationManager.getResource(sessionFactory)

    if (sessionHolder) {
         sessionHolder.clear()
    }
}

集成測試將執行以下操作

  • 開始交易
  • 運行測試
  • 回滾事務

通常,這將工作並將數據庫狀態重置為測試之前的狀態。 但是,如果您的測試邏輯將以特定方式處理事務,那么您將遇到問題。 一個例子是使用propagation = REQUIRES_NEW在測試代碼中創建自己的事務。 無論您在該事務中執行了什么操作,都無法通過測試邏輯回滾。

通常這樣的代碼會打破測試之間的獨立性。 唯一真正安全的方法是讓每個測試以空數據庫開始並插入所需的內容......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM