Transactional Testing for Multiple Databases in ActiveRecord
March 18, 2010We've been working on an app that needs to stand astride two databases - one local DB for the app itself, and another with restrictive policies about modifications that is nonetheless authoritative on many subjects. There's a fair amount of tricky interaction between the two, and testing has been a delightful challenge.
We're using the use_db plugin, and all it takes to make testing transactions happen around multiple DBs is:
In: spec/spec_helper.rb
require 'override_test_callbacks'
My concern comes from the fact that this is a direct and unfiltered monkeypatch on ActiveRecord::TestFixtures. So it relies on use_transactional_fixtures (which could certainly be used without using actual fixures, granted), and if the test transaction code moves within Rails, that's another integration to worry about. Or if we add a spec that doesn't wind up making ActiveRecord::TestFixtures load... Or if we decide to use something other than use_db...
So instead I'm using:
Spec::Runner.configure do |config| config.prepend_before do (UseDbPlugin.all_use_dbs - [ActiveRecord::Base]).each do |db| db.connection.increment_open_transactions db.connection.transaction_joinable = false db.connection.begin_db_transaction end end config.append_after do (UseDbPlugin.all_use_dbs - [ActiveRecord::Base]).reverse.each do |db| db.connection.rollback_db_transaction db.connection.decrement_open_transactions end end end
If we weren't already using transactional fixtures, I might pull out the - [ActiveRecord::Base]. And if we were to change off of use_db, there's one place to change the transaction code. Finally, there's much less dependence on the innards of ActiveRecord - only it's published API.
Add A Comment