0

我有两个看起来像这样的 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

4

1 回答 1

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
于 2013-01-17T03:24:02.293 回答