Unit testing Grails2.4.5控制器单元测试验证事务已回滚
这是一个简单的控制器Unit testing Grails2.4.5控制器单元测试验证事务已回滚,unit-testing,grails,Unit Testing,Grails,这是一个简单的控制器 class UserController { @Transactional def update() { try { .... throw new Exception("test transaction rollback") ... } catch( e ) { transactionStatus.setRollbackOnly() respond "{ "s
class UserController {
@Transactional
def update() {
try {
....
throw new Exception("test transaction rollback")
...
} catch( e ) {
transactionStatus.setRollbackOnly()
respond "{ "status":"error" }"
}
}
}
这是一个单元测试规范
@TestFor(UserController)
class UserControllerSpec extends Specification {
when:''
controller.update()
then:'verify that transaction has been rolled back'
// it fails with missing property, whats the best way to check that it was rolled back ?
controller.transactionManager.transactionRolledBack == true
}
测试事务是否已回滚的最佳方法是什么
@BurtBeckwith suggestion之后尝试了一个集成规范
//域用户.groovy
class User { String firstName; String lastName }
//UserController.groovy
class UserController {
static responseFormats = ['json', 'xml']
static allowedMethods = [update: 'PUT']
@Transactional
def update( UserCommand cmd ) {
User m = User.get(id)
m.firstName=cmd.firstName
m.lastName=cmd.lastName
m.save(failOnError:true,flush:true)
transactionStatus.setRollbackOnly()
}
}
class UserCommand { Long id; String firstName; String lastName }
//IntegrationSpec UserControllerIntegrationSpec.groovy
import grails.test.spock.IntegrationSpec
class UserControllerIntegrationSpec extends IntegrationSpec {
def controller
def sessionFactory
def setup() {
controller = new UserController()
}
void "test transaction rollback"() {
given:'a user'
User u = new User(firstName:'oldFirstName',lastName:'oldLastName')
u.save(flush:true,failOnError:true)
controller.request.method='PUT'
controller.request.contentType = "application/json"
controller.request.content = '{"id":u.id,"firstName":"newFirstName","lastName":"newLastName"}'.getBytes()
when:'an update that rollsback is called'
controller.update()
// clear so that we do not get data from cache.
sessionFactory.currentSession.flush()
sessionFactory.currentSession.clear()
then:'we should still see old data'
User u2 = User.get(u.id)
// The following fails, u.firstName has 'newFirstName' which is wrong on rollback
u2.firstName == 'oldFirstName'
u2.lastName == 'oldLastName'
}
}
//DataSource.groovy
test {
dataSource {
url = "jdbc:mysql://localhost/starter_app_test"
driverClassName = "com.mysql.jdbc.Driver"
pooled = true
properties {
...
defaultAutoCommit=false
}
}
}
您知道为什么即使在回滚时,集成测试数据也会持久化吗?至少您需要使用集成测试,因为单元测试中使用的GORM不使用数据库,只使用由ConcurrentHashMap支持的内存存储。感谢@BurtBeckwith创建了一个集成规范,有趣的是,即使在调用“setRollbackOnly()”之后,数据似乎仍然存在