Testing and Establishing a Connection

How to write tests for projects that use establish_connection in the model to connect to another database?

+4
source share
3 answers

When you establish a connection for certain models to connect to another database, one of the problems you encountered while testing these tables is that the test data you created is automatically rolled back.

The actual code to create the transaction save point and rollback data for test lives in rails/activerecord/lib/active_record/fixtures.rb . And especially there are two methods setup_fixtures and teardown_fixtures . The code in these methods is straightforward. They simply create a savepoint and roll back for each test. But it only works for an ActiveRecord::Base connection.

So what you need to do is the โ€œmonkey patchโ€ of these methods, so in addition to the ActiveRecord::Base connection, the same set of operations is performed for your additional database connection.

Here is a sample code for it:

 ## database.yml development: database: dev test: database: test #... my_connection_development: database: my_connection_dev my_connection_test: database: my_connection_test #... ## my_connection_base.rb class MyConnectionBase < ActiveRecord::Base establish_connection(ActiveRecord::Base.configurations["my_connection_#{RAILS_ENV}"]) self.abstract_class = true end ## my_model.rb class MyModel < MyConnectionBase end ## my_another_model.rb class MyAnotherModel < MyConnectionBase end ## test_case_patch.rb module ActiveSupport class TestCase def setup_fixtures return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank? if pre_loaded_fixtures && !use_transactional_fixtures raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures' end @fixture_cache = {} @@already_loaded_fixtures ||= {} # Load fixtures once and begin transaction. if run_in_transaction? if @@already_loaded_fixtures[self.class] @loaded_fixtures = @@already_loaded_fixtures[self.class] else load_fixtures @@already_loaded_fixtures[self.class] = @loaded_fixtures end ActiveRecord::Base.connection.increment_open_transactions ActiveRecord::Base.connection.transaction_joinable = false ActiveRecord::Base.connection.begin_db_transaction MyConnectionBase.connection.increment_open_transactions MyConnectionBase.connection.transaction_joinable = false MyConnectionBase.connection.begin_db_transaction # Load fixtures for every test. else Fixtures.reset_cache @@already_loaded_fixtures[self.class] = nil load_fixtures end # Instantiate fixtures for every test if requested. instantiate_fixtures if use_instantiated_fixtures end def teardown_fixtures return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank? unless run_in_transaction? Fixtures.reset_cache end # Rollback changes if a transaction is active. if run_in_transaction? && MyConnectionBase.connection.open_transactions != 0 MyConnectionBase.connection.rollback_db_transaction MyConnectionBase.connection.decrement_open_transactions end # Rollback changes if a transaction is active. if run_in_transaction? && ActiveRecord::Base.connection.open_transactions != 0 ActiveRecord::Base.connection.rollback_db_transaction ActiveRecord::Base.connection.decrement_open_transactions end MyConnectionBase.clear_active_connections! ActiveRecord::Base.clear_active_connections! end end end 
+10
source

I donโ€™t see the need to change the test codes after you set connection_connection in your model, as you are still testing the same model functionality.

0
source

You do not need to test the connection_setter method like its activrecord method and is well tested before release.

although, if you still want to do this, call the method in another method and see if you can connect to the corresponding tables in this database.

-2
source

All Articles