我有两个看起来像这样的ActiveRecord模型:
class Foo < ActiveRecord::Base
after_commit { puts 'after commit in Foo' }
end
class Bar < ActiveRecord::Base
after_commit { puts 'after commit in Bar' }
end
然后我有两个看起来像这样的测试:
测试/单元/ foo_test.rb
class FooTest < ActiveSupport::TestCase
setup do
puts 'Creating Foo'
@foo = Foo.create
end
should 'foo exists' do
assert !@foo.nil?
end
end
测试/单元/ bar_test.rb:
class BarTest < ActiveSupport::TestCase
self.use_transactional_fixtures = false
setup do
pits 'Creating Bar'
@bar = Bar.create
end
should 'bar exists' do
assert !@bar.nil?
end
end
但是当我一起运行这些测试时,我得到以下输出:
Creating Foo
Creating Bar
after commit in Foo
after commit in Bar
我的印象是,默认情况下Rails将事务中的活动记录包装在一起,然后在每次测试结束时进行回滚。我已经尝试显式设置use_transactional_fixtures = true但是没有产生任何结果。
我的问题是这里发生了什么?似乎活动记录正在为Bar创建回调链,然后在测试完成后它不会被清除。我也尝试过使用DatabaseCleaner并在测试结束时在拆解回调中明确地销毁@bar,但这些都没有用。
编辑:看起来它可能是rails中的问题:https://github.com/rails/rails/pull/3300
答案 0 :(得分:1)
原来在rails中存在一个错误,导致事务中的记录即使在回滚实际数据库之后仍然存在。以下是讨论:https://github.com/rails/rails/pull/3300
如果需要,您可以使用以下方法(如github线程中所建议的)清除测试运行之间的活动事务:
def teardown_fixtures
if run_in_transaction? && ActiveRecord::Base.connection.open_transactions != 0
ActiveRecord::Base.connection.rollback_db_transaction
ActiveRecord::Base.connection.send(:rollback_transaction_records, true)
if ActiveRecord::Base.connection.instance_variable_get('@_current_transaction_records')
ActiveRecord::Base.connection.decrement_open_transactions
end
ActiveRecord::Base.clear_active_connections!
end
end