Reputation: 5151
I have two ActiveRecord models that looks like this:
class Foo < ActiveRecord::Base
after_commit { puts 'after commit in Foo' }
end
class Bar < ActiveRecord::Base
after_commit { puts 'after commit in Bar' }
end
And then I have two tests that look like this:
test/unit/foo_test.rb
class FooTest < ActiveSupport::TestCase
setup do
puts 'Creating Foo'
@foo = Foo.create
end
should 'foo exists' do
assert [email protected]?
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 [email protected]?
end
end
But when I run these tests together I get the following output:
Creating Foo
Creating Bar
after commit in Foo
after commit in Bar
I was under the impression that Rails by default wrapped the active record stuff in a transaction and then did a rollback at the end of each test. I have tried explicitly setting use_transactional_fixtures = true but that has not yielded any results.
My question is what is going on here? It would seem that active record is creating the callback chain for Bar and then it's not getting cleared out after the test is done. I have also tried using DatabaseCleaner and explicitly destroying @bar in a teardown callback at the end of the test but none of that has worked.
Edit: Looks like it could be a problem in rails: https://github.com/rails/rails/pull/3300
Upvotes: 0
Views: 147
Reputation: 5151
Turns out there's a bug in rails that causes records in a transaction to stick around even after the actual database has been rolled back. Here is the discussion: https://github.com/rails/rails/pull/3300
You can use the following method (as suggested in the github thread) to clear the active transactions between test runs if needed:
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
Upvotes: 1