0

次のような ActiveRecord モデルが 2 つあります。

class Foo < ActiveRecord::Base
  after_commit { puts 'after commit in Foo' }
end

class Bar < ActiveRecord::Base
   after_commit { puts 'after commit in Bar' }
end

そして、次のような 2 つのテストがあります。

テスト/ユニット/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 を明示的に破棄しようとしましたが、いずれも機能しませんでした。

編集: レールの問題のようです: 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 に答える