测试和establish_connection
题
我如何写上使用项目的测试establish_connection
模型连接到另一个数据库?
解决方案
当这样做对于某些型号establish_connection连接到不同的数据库中,同时检测这些表,你会面临的问题之一是,测试数据创建你不会被回自动回滚。
在实际的代码来创建事务保存点和回滚测试生命rails/activerecord/lib/active_record/fixtures.rb
的数据。特别是有两种方法setup_fixtures
和teardown_fixtures
。在这些方法中的代码是直线前进。他们只需要创建一个保存点,并不会回滚每个测试。但它确实只为ActiveRecord::Base
连接。
所以,你必须做的是“猴子补丁”这些方法,这样,除了<=>连接,同一套操作都为你额外的数据库连接完成的。
下面是对于相同的试样代码:
## 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
其他提示
我不认为有必要改变测试代码放置establish_connection后您的模型,因为你还是测试同一型号的功能。
您将不需要测试establish_connection方法,作为其一个activrecord方法和是行之有效的,释放之前。
但如果你仍然想这样做,调用不同的方法中的方法,看看你是否可以连接到适当的表在数据库中。
不隶属于 StackOverflow