我有一个Project类,其中包含两个与ObjectSpace相关的方法:
def self.all
ObjectSpace.each_object(self).to_a
end
def self.count
ObjectSpace.each_object(self).count
end此规范失败:
it "can print all projects" do
Project.all.should eq([@project1, @project2])
end出现以下错误:
Failure/Error: Project.all.should eq([@project1, @project2])
expected: [#<Project:0x007fd76a815508 @name="Building house", @tasks=[]>, #<Project:0x007fd76a815198 @name="Getting a loan from the Bank", @tasks=[]>]
got: [#<Project:0x007fd7688336b8 @name="Building house", @tasks=[]>, #<Project:0x007fd7688dae40 @name="Building house", @tasks=[]>, #<Project:0x007fd768af4de8 @name="Getting a loan from the Bank", @tasks=[]>, #<Project:0x007fd768af5090 @name="Building house", @tasks=[]>, #<Project:0x007fd76a815198 @name="Getting a loan from the Bank", @tasks=[]>, #<Project:0x007fd76a815508 @name="Building house", @tasks=[]>]正如您所看到的,这为我提供了两倍于数组中的对象,但代码本身运行良好。那么为什么我的测试失败了呢?
发布于 2013-01-14 23:07:16
因为先前存在的Project仍然作为对象存在。
这意味着它们仍然可以在ObjectSpace中找到,并且您将拥有比预期更多的对象。
发布于 2013-01-14 23:45:26
ObjectSpace可能含有微量坚果
嗯,不是这样的。但ObjectSpace通常包含属于其他作用域的对象,已标记为垃圾回收但尚未删除的对象,或者(特别是在RSpec测试的情况下)来自多次调用before块的对象的副本。
Ruby2.0可能会有所不同,但早期的MRI解释器并不保证垃圾回收,所以即使手动运行ObjectSpace,也不能真正指望GC.start的内容对相等性测试有效。
重构你的代码
与其在您的规范中寻求平等,您可以考虑:
在测试中的类以及测试本身的ObjectSpace.
你可以在这里混合搭配,但是修复你的测试实际上只是问题的一部分。底层应用程序逻辑似乎需要重构。
失败的测试是好的,因为它突出了一个需要手术的类。不要只是修改测试;要倾听规范试图告诉您的关于被测类的信息。
发布于 2013-01-15 00:37:04
project_spec.rb
describe Project do
let(:p1) { Project.new }
let(:p2) { Project.new }
describe ".all" do
it "should keep track of all pr" do
Project.all.should == [p1, p2]
end
end
describe ".count" do
it "should count all the projects" do
Project.count.should == 2
end
end
endproject.rb
class Project
@@all_projects = []
def initialize(options=nil)
@@all_projects << self
end
def self.all
@@all_projects
end
def self.count
@@all_projects.count
end
end
Finished in 0.00079 seconds
2 examples, 0 failures我将留给您来解决其他细节,这些细节对于您的项目来说可能是具体而复杂的。希望这对你有用。
https://stackoverflow.com/questions/14320907
复制相似问题