我正在为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技巧,但即使它被替换,在参与者关联中引用的类也不会发生同样的事情
在很少的话中,belongs_to,在第一次调用之后,检索第一个/错误/已取消/未引用的TestModel。除了这种情况,使用Rspec测试不同类配置的好模式是什么?当然,单独运行测试可以使所有工作正常,这是正确的模式吗?
答案 0 :(得分:0)
我无法理解为什么你使用这种困难的方式创建和销毁对象(通过:remove_const和文件加载)。 Ruby有一个垃圾收集器,所以只需使用TestModel.new.is_a_limesurvey_participant(opts = {different_options})创建对象,不要担心会破坏它们。
至于 puts 并且它应该始终打印为true:我认为 LimesurveyRails :: SurveyParticipation 的所有反映关联(reflect_on_all_associations)的数组总是不会返回当前对象的第一个元素。
LimesurveyRails::SurveyParticipation.reflect_on_all_associations.first.klass.object_id
当你运行单独的测试时,那么关联数组(在rails加载到内存之后)只有一个元素而reflect_on_all_associations.first工作正常。但是对于每个下一个测试,第一个元素都不会是实际的。
可能的一种解决方法是尝试将reflect_on_all_associations更改为reflect_on_association
reflect_on_all_associations.first.klass.object_id
-->
reflect_on_association(:belongs_to).klass.object_id