tester et établir_connexion
Question
Comment puis-je écrire des tests pour des projets qui utilisent établissent_connexion
dans le modèle pour se connecter à une autre base de données?
La solution
Lorsque vous établissez_connection pour que certains modèles se connectent à une base de données différente, l'un des problèmes que vous rencontriez lors du test de ces tables est que les données de test que vous avez créées ne seront pas automatiquement restaurées.
Le code permettant de créer un point de sauvegarde des transactions et d’annuler les données à des fins de test dans rails / activerecord / lib / enregistrement_actif / fixtures.rb
. Et surtout, il existe deux méthodes setup_fixtures
et teardown_fixtures
. Le code dans ces méthodes sont simples. Ils créent simplement un point de sauvegarde et effectuent une restauration pour chaque test. Mais cela ne concerne que la connexion ActiveRecord :: Base
.
Ce que vous devez faire est donc "Monkey Patch". ces méthodes pour que, en plus de la connexion ActiveRecord :: Base
, le même ensemble d'opérations soit effectué pour votre connexion de base de données supplémentaire.
Voici un exemple de code pour la même chose:
## 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
Autres conseils
Je ne vois pas la nécessité de modifier les codes de test après avoir placé Establ_connection dans votre modèle, car vous testez toujours les mêmes fonctionnalités.
Vous n’aurez pas besoin de tester la méthode établissant_connexion, car c’est une méthode d’activrecord et elle est bien testée avant la publication.
Toutefois, si vous souhaitez toujours le faire, appelez la méthode dans une méthode différente et voyez si vous pouvez vous connecter aux tables appropriées de cette base de données.