2016-07-29 85 views
0

我正在使用Ruby 2.2.1和Rails 4.2.0Rspec测试重用对象

我正在添加测试用例来覆盖模块。该模块基本上对从另一个系统提取的数据执行一些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对象。有没有办法强制它在循环中实例化一个新对象?

+0

有一个可怕的方法,可能有更好的方法,但我们需要看到更多的代码。 'Qa'中的其他方法是指'@ trips'?什么课包括'Qa'?测试中的“主题”是什么? ([RSpec的主题大多是一件坏事。](http://stackoverflow.com/questions/38437162/whats-the-difference-between-rspecs-subject-and-let-when-should-they-be-used) ) –

回答

0

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

案例1和案例2在原来的问题实际上是使用Qa类的同一个实例,所以当然的实例变量是怎么回事,因为我用的是||=运营商仍然包含原来的trip对象。

我解决了这个问题,在Qa.instance_variable_set(:@trips, [])的相关上下文的开头添加了一个before(:each)块,以确保该变量以干净状态启动。

+0

是的,或者你可以做适当的OOP,而不是以全局状态存储数据。意思是,实际实例化一个'Qa'类并且使用__instance__而不是__class__。 –