我试图让事务在 Grails 服务中工作,但我没有得到我期望的结果。如果我做错了什么,如果我的假设不成立,有人可以告诉我吗?
我的域类:
class Account {
static constraints = {
balance(min: 0.00)
}
String companyName
BigDecimal balance = 0.00
Boolean active = true
String toString() {
return "${companyName} : ${balance}"
}
}
我的服务:
class AccountService {
static transactional = true
def transfer(Account source, Account destination, amount) throws RuntimeException {
if (source.active && destination.active) {
source.balance -= amount
if (!source.save(flush: true)) {
throw new RuntimeException("Could not save source account.")
} else {
destination.balance += amount
if (!destination.save(flush: true)) {
throw new RuntimeException("Could not save destination account.")
}
}
} else {
throw new RuntimeException("Both accounts must be active.")
}
}
def someMethod(Account account) throws RuntimeException {
account.balance = -10.00
println "validated: ${account.validate()}"
if(!account.validate()) {
throw new RuntimeException("Rollback!")
}
}
}
我的单元测试: import grails.test.*
class AccountServiceTests extends GrailsUnitTestCase {
def AccountService
protected void setUp() {
super.setUp()
mockDomain(Account)
AccountService = new AccountService()
}
protected void tearDown() {
super.tearDown()
}
void testTransactional() {
def account = new Account(companyName: "ACME Toy Company", balance: 2000.00, active: true)
def exception = null
try {
AccountService.someMethod(account)
} catch (RuntimeException e) {
exception = e
}
assert exception instanceof RuntimeException
println "exception thrown: ${exception.getMessage()}"
assertEquals 2000.00, account.balance
}
}
结果:
Testsuite: AccountServiceTests
Tests run: 1, Failures: 1, Errors: 0, Time elapsed: 1.068 sec
------------- Standard Output ---------------
--Output from testTransactional--
validated: false
exception thrown: Rollback!
------------- ---------------- ---------------
------------- Standard Error -----------------
--Output from testTransactional--
------------- ---------------- ---------------
Testcase: testTransactional took 1.066 sec
FAILED
expected:<2000.00> but was:<-10.00>
junit.framework.AssertionFailedError: expected:<2000.00> but was:<-10.00>
at AccountServiceTests.testTransactional(AccountServiceTests.groovy:89)
at _GrailsTest_groovy$_run_closure4.doCall(_GrailsTest_groovy:203)
at _GrailsTest_groovy$_run_closure4.call(_GrailsTest_groovy)
at _GrailsTest_groovy$_run_closure2.doCall(_GrailsTest_groovy:147)
at _GrailsTest_groovy$_run_closure1_closure19.doCall(_GrailsTest_groovy:113)
at _GrailsTest_groovy$_run_closure1.doCall(_GrailsTest_groovy:96)
at TestApp$_run_closure1.doCall(TestApp.groovy:66)
at gant.Gant$_dispatch_closure4.doCall(Gant.groovy:324)
at gant.Gant$_dispatch_closure6.doCall(Gant.groovy:334)
at gant.Gant$_dispatch_closure6.doCall(Gant.groovy)
at gant.Gant.withBuildListeners(Gant.groovy:344)
at gant.Gant.this$2$withBuildListeners(Gant.groovy)
at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
at gant.Gant.dispatch(Gant.groovy:334)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.processTargets(Gant.groovy:495)
at gant.Gant.processTargets(Gant.groovy:480)
我的期望:
当账户的余额为负时,它不应该验证(它不验证),应该抛出一个 RuntimeException(它是),并且账户应该回滚到它之前的状态(余额:2000),即它分崩离析的地方。
我在这里想念什么?