【发布时间】:2014-03-26 16:32:45
【问题描述】:
我正在为 Ruby On Rails 引擎编写 Rspec 测试。我的引擎为 ActiveRecord 模型提供了一个类方法is_a_limesurvey_participant(opts = {}),它使用类变量和关联来扩展它们。要测试我的 TestModel 扩展,我需要在提供不同选项的不同且连续的 RSpec 上下文中对其进行多次初始化。为此,我需要取消定义我的 TestModel 否则它将“记住”旧设置。在受this 启发的测试之前,我会调用以下实用程序方法:
def reset_test_model
Object.send(:remove_const,'TestModel')
load File.join(ENGINE_RAILS_ROOT,'spec','dummy','app','models','test_model.rb')
end
没关系。
这就是问题所在。我的引擎有一个模型(SurveyParticipation),它需要与我的主应用程序 TestModel 关联。我在我的 is_a_limesurvey_participant 方法中这样做:
def is_a_limesurvey_participant(opts = {})
# ... class variables definitions
has_many :survey_participations, :class_name => "LimesurveyRails::SurveyParticipation", :foreign_key => "participant_id"
LimesurveyRails::SurveyParticipation.belongs_to :participant, :class_name => self.name, :foreign_key => 'participant_id'
puts (LimesurveyRails::SurveyParticipation.reflect_on_association(:participant).klass.object_id == self.object_id)
end
每次我的 TestModel 调用 is_a_limesurvey_participant 方法时,我希望 puts 调用始终显示正确的任何示例,因为 LimesurveyRails::SurveyParticipation.reflect_on_association(:participant).klass 应该是当前的 TestModel,所以如果我运行我的测试分别地。
但是一起运行我的测试表明 LimesurveyRails::SurveyParticipation.reflect_on_association(:participant).klass 始终引用相同的 TestModel 对象,即 Rspec 第一次运行 is_a_limesurvey_participant 方法时的当前对象。
如果我尝试通过 object_id 检索两个对象,我可以看到它们都存在于 ObjectSpace 中:
(rdb:1) ObjectSpace._id2ref(70222826866840)
TestModel(id: integer, name: string, surname: string, email_address: string, extra_id: string, created_at: datetime, updated_at: datetime)
(rdb:1) ObjectSpace._id2ref(70222827277420)
TestModel(id: integer, name: string, surname: string, email_address: string, extra_id: string, created_at: datetime, updated_at: datetime)
我也尝试对 LimesurveyRails::SurveyParticipation 类执行相同的 reset_test_model 技巧,但即使它被替换,它在 :participant 关联中的引用类也不会发生同样的情况
简而言之,belongs_to,在第一次调用之后,检索第一个/错误/取消/未引用的 TestModel。除了这种情况,用 Rspec 测试不同类配置的好模式是什么?当然,单独运行测试可以让所有工作正常,这是正确的模式吗?
【问题讨论】:
标签: ruby-on-rails ruby rspec metaprogramming