Frage

Wie kann ich schreiben Tests für Projekte, die establish_connection in Modell verwenden, um eine andere Datenbank zu verbinden?

War es hilfreich?

Lösung

Wenn Sie establish_connection für bestimmte Modelle tun in eine andere Datenbank zu verbinden, von dem Problem würde stehen Sie während die Tabellen testen, dass die Testdaten Sie werden nicht automatisch zurückgerollt werden erstellt.

Der eigentlichen Code, um eine Transaktion speichert Punkt zu erstellen und die Daten rückgängig zu machen für den Test in rails/activerecord/lib/active_record/fixtures.rb lebt. Und vor allem gibt es zwei Methoden setup_fixtures und teardown_fixtures. Der Code in diesen Verfahren sind geradlinig. Sie schaffen nur einen Speicherpunkt und ist für jeden Test ein Rollback. Aber es funktioniert nur für die ActiveRecord::Base Verbindung.

Also, was Sie tun müssen, ist „Affe Patch“ diese Methoden, so dass neben der ActiveRecord::Base Verbindung, die gleiche Menge von Operationen für die zusätzliche Datenbankverbindung fertig sind.

Hier ist ein Beispielcode für das gleiche:

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

Andere Tipps

Ich sehe keine Notwendigkeit, die Testcodes zu ändern, nachdem Sie establish_connection in Ihrem Modell platzieren, da Sie immer noch die gleiche Modell Funktionalität testen.

Sie werden nicht die establish_connection Methode testen müssen, als eine activrecord Methode und gut getestet wird, vor der Freigabe.

obwohl, wenn Sie immer noch so tun wollen, die Methode in einem anderen Verfahren nennt, und sehen, ob Sie zu entsprechenden Tabellen in dieser DB verbinden kannst.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top