Pregunta

¿Cómo escribo pruebas para proyectos que usan establo_conexión en el modelo para conectarse a otra base de datos?

¿Fue útil?

Solución

Cuando estableces una conexión para que ciertos modelos se conecten a una base de datos diferente, uno de los problemas que enfrentarías al probar esas tablas es que los datos de prueba que creaste no se revertirán automáticamente.

El código real para crear un punto de guardado de transacción y revertir los datos para las vidas de prueba en rails / activerecord / lib / active_record / fixtures.rb . Y especialmente hay dos métodos setup_fixtures y teardown_fixtures . El código en esos métodos es sencillo. Simplemente crean un punto de rescate y retroceden para cada prueba. Pero solo lo hace para la conexión ActiveRecord :: Base .

Entonces, lo que tienes que hacer es "parche de mono" estos métodos para que, además de la conexión ActiveRecord :: Base , se realice el mismo conjunto de operaciones para su conexión de base de datos adicional.

Aquí hay un código de muestra para el mismo:

## 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

Otros consejos

No veo la necesidad de cambiar los códigos de prueba después de que establezca establecer_conexión en su modelo, ya que todavía prueba la misma funcionalidad del modelo.

No necesitará probar el método establecer_conexión, ya que es un método activrecord y está bien probado, antes del lanzamiento.

aunque si todavía desea hacerlo, llame al método dentro de un método diferente y vea si puede conectarse a las tablas apropiadas en ese DB.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top