我有一个带有两个与ObjectSpace相关的方法的Project类:
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=[]>]
正如你所看到的,这给了我一个数组加倍的对象,但代码本身工作正常。那么为什么我的测试失败了?
答案 0 :(得分:2)
因为以前存在的Project
仍然作为对象存在。
这意味着它们仍会在ObjectSpace
中找到,并且您将拥有比预期更多的对象。
答案 1 :(得分:1)
嗯,不是真的。但是ObjectSpace通常包含属于其他范围的对象,已标记为垃圾收集但尚未删除的对象,或者(特别是RSpec测试的情况下)来自前一个块的多个调用的对象副本。
Ruby 2.0可能有所不同,但早期的MRI解释器不保证垃圾收集,因此即使您手动运行{{3},也无法真正指望ObjectSpace的内容对于相等测试有效。 }。
您可以考虑:
,而不是在规范中寻找相等性你可以在这里混合搭配,但修复你的测试只是问题的一部分。底层应用程序逻辑似乎需要重构。
失败的测试很好,因为它突出了需要手术的课程。不要只是修复测试;听听规范试图告诉你关于被测试课程的内容。
答案 2 :(得分:1)
<强> 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
end
<强> project.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
我会告诉你,你可以找出可能对你的项目特别复杂的其他细节。希望这对你有用。