我正在Grails 3中使用Spock進行測試。由於在這種情況下,Grails在兩個不同的會話中對我的數據庫說話,所以特定的測試用例正在中斷。我的規範註釋了@Rollback
,以回滾每個測試所做的所有更改。如何在特定方法中防止@Rollback?
是否有辦法爲這一個方法禁用@Rollback
,然後在測試完成後手動回滾更改?
更新
一個精簡例如我的測試規範的是以下:
@Log4j
@Integration
@Rollback
class PublicationReportBreakingSpec extends Specification {
@Unroll
@Rollback
void "Invalidate #type object and check not in report"(type, status, hits, expect)
{
//We want to roll back the changes made to the publication after each pass.
given: "Find a valid #type publication"
//Finding publication which is Read (valid, should appear in report)
final Publication pub = getSinglePub(type, status, hits)
//Set publication to be Unread (invalid, shouldn't appear in report)
when: "The #type publication is altered to fail"
pub.setStatus('Unread')
pub.save(flush:true, failOnError: true)
then: "Check the properties match the test case"
pub.status = 'Unread'
//Generate report of read publications
when: "The report is run"
def resp = PublicationController.reportReadPublications()
//Make sure report doesn't contain the publication
then: "Check for expected result #expect"
checkReportExpectedResult(resp, expect)
where:
clause | type | status | hits || expect
"Book is unread" | 'Book' | 'Read' | 1200 || 0
"Article is unread" | 'Article' | 'Read' | 200 || 0
}
//Checks report for expect value
public void checkReportExpectedResult(resp, expect){...}
//Returns single publication based on passed in parameters
public Publication getSinglePub(type, status){...}
}
該錯誤的堆棧跟蹤是:
<testcase name="Testing breaking domain class changes. Book is unread" classname="com.my.project.PublicationReportBreakingSpec" time="118.216">
<failure message="java.lang.IllegalStateException: No transactionManager was specified. Using @Transactional or @Rollback requires a valid configured transaction manager. If you are running in a unit test ensure the test has been properly configured and that you run the test suite not an individual test method." type="java.lang.IllegalStateException">java.lang.IllegalStateException: No transactionManager was specified. Using @Transactional or @Rollback requires a valid configured transaction manager. If you are running in a unit test ensure the test has been properly configured and that you run the test suite not an individual test method.
at grails.transaction.GrailsTransactionTemplate.<init>(GrailsTransactionTemplate.groovy:60)
at com.my.project.PublicationReportBreakingSpec (Removed due to sensitivity)
at com.my.project.PublicationReportBreakingSpec (Removed due to sensitivity)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
at com.my.project.PublicationReportBreakingSpec.Invalidate #type object and check not in report. Check #clause, publication type #type(PublicationReportBreakingSpec.groovy)
您無法回滾典型的Geb測試。自從它發生在另一個線程上後,您無法控制交易 –
好吧,這是有道理的。所以使用@Rollback是多餘的,即使它編譯?那麼我怎麼做我的測試?我正在更改一個域對象並將其保存到數據庫中,但是看起來好像另一個會話正在運行導致它失敗的測試用例,並且它不會保存對對象的保存更改。我正在做'.save(flush:true)'我做的任何修改。 – Donglecow
編輯的OP:對不起,我只是注意到了文章中的一個錯字。我正在使用Spock而不是Geb進行測試。 – Donglecow