cri*_*imi 7 rspec ruby-on-rails ruby-on-rails-4 database-cleaner
在使用MySql的Rails 4.0应用程序中,我们将rspec与使用strategy:transaction配置的database_cleaner gem一起使用,以清理每个测试用例的数据库.如果我们有自定义事务,应该回滚,它不起作用.
没有database_cleaner gem并且只使用标准方式:
config.use_transactional_fixtures = true
Run Code Online (Sandbox Code Playgroud)
一切都如预期的那样.但是对于使用JavaScript运行功能测试,我们需要database_cleaner将夹具删除策略更改为:截断.
我们如何将database_cleaner与自定义事务一起使用?为什么它与标准的rspec事务策略不同?
Mik*_*rin 11
问题是database_cleaner在测试结束时调用ActiveRecord.rollback - 您也在代码中使用它.InnoDB/MySQL不支持真正的嵌套事务,因此代码中的嵌套事务不会被视为事务,除非明确调用它们.
考虑这个块(来自ActiveRecord文档):
User.transaction do
User.create(username: 'Kotori')
User.transaction do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
Run Code Online (Sandbox Code Playgroud)
回滚电话后您期望发生什么?你希望它能够回滚Nemu用户,然后把你留给Kotori,对吧?那么,实际发生的是Kotori和Nemu都是创造出来的.回滚不会触发,因为您处于嵌套事务中(并且AR当前只关心父事务)并且父事务(具有实际的db事务)没有看到回滚调用 - 因为它在孤立的街区.有点奇怪.
方案:
Klass.transaction(requires_new: true)
Run Code Online (Sandbox Code Playgroud)
如果设置requires_new,ActiveRecord将使用或伪使用嵌套事务(对于Postgres,它将进行嵌套事务,对于MySQL/InnoDB,它将创建保存点).当您使用ActiveRecord调用回滚时,它将确定其范围并发出正确的回滚.
另一种解决方案是使用截断或删除作为涉及事务的测试的策略.
| 归档时间: |
|
| 查看次数: |
1751 次 |
| 最近记录: |