我是Spock粉丝,我试图向大家展示其奇迹。但大部分时间他们都会回到我身边并告诉我他们无法使用Grails中的IntegrationSpecs来处理事务性服务。我自己很多次遇到这种麻烦,总是设法用一两招来解决它,但现在我想知道发生了什么。
我做了一个简单的例子,我需要在对数据库的任何查询返回预期行为之前清除会话。
static transactional = false
def cleanup() {
deleteAllBills()
}
@Unroll
void "update all opened Bills to status CLOSED"() {
given:
createAndSaveOpenBill()
when:
def rowsUpdated = billTransitionService."$method"()
and:
if (clearSession) {
sessionFactory.getCurrentSession().clear()
}
then:
rowsUpdated == 1
then:
def bills = Bill.findAll()
bills.status.every { it == 'CLOSED' }
where:
desc | method | clearSession
'where and update' | 'transitionOpenToClosed' | false
'where and update' | 'transitionOpenToClosed' | true
'findAll and update' | 'transitionOpenToClosedLoop' | false
'findAll and update' | 'transitionOpenToClosedLoop' | true
}
@Transactional
def createAndSaveOpenBill() {
new Bill(status: 'OPEN').save(failOnError: true)
}
@Transactional
void deleteAllBills() {
Bill.findAll()*.delete()
}
并且服务也非常简单
import grails.transaction.Transactional
@Transactional
class BillTransitionService {
def transitionOpenToClosed() {
Bill.where { status == 'OPEN' }.updateAll(status: 'CLOSED')
}
def transitionOpenToClosedLoop() {
def billsToClose = Bill.findAllByStatus('OPEN')
billsToClose*.status = 'CLOSED'
return billsToClose.size()
}
}
第一次测试失败,其他三次测试完美。这个例子是用Grails 2.4.4制作的,但是自2.2.3以来几乎每个版本都有同样的问题。
如果您想亲自尝试https://github.com/juandiegoh/grails-spock-transactions
,则此处的代码在线编辑:我使用GroovyTestCase和JUnit 4实现了相同的测试,问题仍在继续,您可以在Github上查看。所以Spock本身不是问题。我很想知道这里发生了什么。