سؤال

وكيف أكتب اختبارات للمشاريع التي تستخدم establish_connection في نموذج للاتصال قاعدة بيانات أخرى؟

هل كانت مفيدة؟

المحلول

وعند القيام establish_connection لبعض النماذج للاتصال قاعدة بيانات مختلفة، واحدة من المشكلة التي ستواجه أثناء اختبار هذه الجداول غير أن البيانات الاختبار الذي تم إنشاؤه لن يكون التراجع تلقائيا.

والرمز الفعلي لإنشاء معاملة حفظ نقطة والتراجع عن البيانات ليعيش اختبار في rails/activerecord/lib/active_record/fixtures.rb. وخصوصا أن هناك طريقتين setup_fixtures وteardown_fixtures. التعليمات البرمجية في هذه الأساليب هي على التوالي إلى الأمام. أنها مجرد إنشاء نقطة حفظ ولا التراجع عن كل اختبار. ولكنه فقط للاتصال ActiveRecord::Base.

وهكذا ما عليك القيام به هو "القرد التصحيح" هذه الأساليب حتى أنه، بالإضافة إلى اتصال 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 ويتم اختباره بشكل جيد، قبل الافراج عنهم.

ولكن إذا كنت لا تزال تريد أن تفعل ذلك، استدعاء الأسلوب في طريقة مختلفة، ومعرفة ما إذا كان يمكنك الاتصال الجداول المناسبة في هذا DB.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top