【问题标题】:Odd behavior with ActiveRecord and TestsActiveRecord 和测试的奇怪行为
【发布时间】:2013-01-17 00:37:18
【问题描述】:

我有两个如下所示的 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

然后我有两个看起来像这样的测试:

test/unit/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

test/unit/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

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多