اختبار وestablish_connection
سؤال
وكيف أكتب اختبارات للمشاريع التي تستخدم 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.