Rspec测试重用对象

时间:2016-07-29 19:48:32

标签: ruby-on-rails ruby rspec

我使用的是Ruby 2.2.1和Rails 4.2.0

我添加测试用例来覆盖模块。该模块基本上对从另一个系统引入的数据进行一些QA检查。我遇到的问题是,在整个测试用例中,模块内部的迭代重复使用相同的对象,而不是单个测试用例的单个对象。

示例测试用例:

...

it "should add issue case 1" do
  trip = FactoryGirl.build(:trip, :case_1)
  p trip.object_id # 7...8660
  subject.do_qa(trip)
  expect(trip.issue_1).not_to be_nil
end

it "should add issue case 2" do
  trip = FactoryGirl.build(:trip, :case_2)
  p trip.object_id # 7...2780
  subject.do_qa(trip)
  expect(trip.issue_2).not_to be_nil
end

...

示例模块:

module Qa

  ...

  def self.do_qa(trips)
    p trips.object_id # Same is the object id in the calling test case
    @trips ||= Array.wrap(trips)
    @trips.each do |t|
      p t.object_id # Always the object id from the first test case!
      ... # Checks for case 1 and case 2
    end
  end

  ...

end

因为循环正在重用对象,所以第二个测试用例永远不会通过,因为模块只是重新评估第一个trip对象。有没有办法强制它在循环中实例化一个新对象?

1 个答案:

答案 0 :(得分:0)

对此的回答最终导致我对Ruby与其他语言缺乏完整的理解。基本上,即使模块没有被定义为类,它仍然是幕后的类,并且实例变量在运行之间保持设置。这在我的应用程序中不是问题,因为没有任何东西依赖于它们在方法调用之间被清除。

原始问题中的案例1和案例2实际上使用了Qa类的相同实例,因此当然实例变量仍将包含原始trip对象,因为我使用||=运营商。

我通过在before(:each)的相关上下文的开头添加Qa.instance_variable_set(:@trips, [])块来解决它,以确保变量以干净状态启动。