Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 为什么从ObjectSpace收集的连续数组在我的规范中不相等?_Ruby_Unit Testing_Garbage Collection_Rspec2_Objectspace - Fatal编程技术网

Ruby 为什么从ObjectSpace收集的连续数组在我的规范中不相等?

Ruby 为什么从ObjectSpace收集的连续数组在我的规范中不相等?,ruby,unit-testing,garbage-collection,rspec2,objectspace,Ruby,Unit Testing,Garbage Collection,Rspec2,Objectspace,我有一个带有两个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/E

我有一个带有两个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=[]>]
失败/错误:Project.all.should eq([@project1,@project2])
预期值:[#,#]
得到:[#、#、#、#、#、#、#、#、#]

正如您所看到的,这将使我的数组中的对象加倍,但代码本身运行良好。那么为什么我的测试失败了呢?

因为以前存在的
项目仍然作为对象存在


这意味着它们仍然可以在
ObjectSpace
中找到,并且您将拥有比预期更多的对象。

因为以前存在的
项目仍然作为对象存在

这意味着它们仍然可以在
ObjectSpace
中找到,并且您将拥有比预期更多的对象。

ObjectSpace可能包含坚果的痕迹 嗯,不是真的。但是ObjectSpace通常包含属于其他作用域的对象、已标记为垃圾收集但尚未删除的对象,或者(特别是在RSpec测试的情况下)来自before块多次调用的对象副本

Ruby 2.0可能有所不同,但早期的MRI解释器不能保证垃圾收集,因此即使手动运行,也不能指望ObjectSpace的内容对相等性测试有效

重构你的代码 与其在规范中寻找平等性,不如考虑:

  • 寻找包含
  • 在ObjectSpace中查找特定的对象ID
  • 重构被测试的类以及测试本身具体来说,使用某种聚合模式,而不是依赖ObjectSpace来保存对您关心的项目对象的引用。
  • 您可以在这里混合搭配,但修复测试实际上只是问题的一部分。底层应用程序逻辑似乎需要重构

    失败的测试是好的,因为它突出了一个需要手术的班级。不要只是修改测试;请听一下规范试图告诉您的关于被测试类的内容。

    ObjectSpace可能包含一些坚果的痕迹 嗯,不是真的。但是ObjectSpace通常包含属于其他作用域的对象、已标记为垃圾收集但尚未删除的对象,或者(特别是在RSpec测试的情况下)来自before块多次调用的对象副本

    Ruby 2.0可能有所不同,但早期的MRI解释器不能保证垃圾收集,因此即使手动运行,也不能指望ObjectSpace的内容对相等性测试有效

    重构你的代码 与其在规范中寻找平等性,不如考虑:

  • 寻找包含
  • 在ObjectSpace中查找特定的对象ID
  • 重构被测试的类以及测试本身具体来说,使用某种聚合模式,而不是依赖ObjectSpace来保存对您关心的项目对象的引用。
  • 您可以在这里混合搭配,但修复测试实际上只是问题的一部分。底层应用程序逻辑似乎需要重构


    失败的测试是好的,因为它突出了一个需要手术的班级。不要只是修改测试;听听规范试图告诉您的关于被测试类的内容。

    project\u 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
    
    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
    
    project.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
    
    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
    
    类项目
    @@所有_项目=[]
    def初始化(选项=nil)
    
    @@所有项目项目规范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
    
    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
    
    project.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
    
    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
    
    类项目
    @@所有_项目=[]
    def初始化(选项=nil)
    
    @@所有的项目啊-你是对的。那么,解决这个问题的正确方法是什么?我应该在上下文之后销毁吗?我该怎么做?@AmitErandole我不确定;你可以从一开始。或者,您可以坚持使用原始解决方案并保留一个引用列表,但在每个规范末尾删除它们。不过,对不起,我不确定最好的主意是什么。嗯,所以我猜使用ObjectSpace是不可能的-这真的是这里要学的课程吗?我想知道…@AmitErandole-您可以在
    项目
    类上定义一个
    终结器
    ,当您执行
    ObjectSpace.garbage\u collect
    时将调用它。但是实现实际上是由一个事实驱动的——你是需要通过你的规范,还是需要实现对上下文严格要求?我想这两者都需要。但我现在想知道的是,我是否应该首先使用
    ObjectSpace
    。让我看看如何使用定稿器啊-你说得对。那么,解决这个问题的正确方法是什么?我应该在上下文之后销毁吗?我该怎么做?@AmitErandole我不确定;你可以从一开始。或者,您可以坚持使用原始解决方案并保留一个引用列表,但在每个规范末尾删除它们。不过,对不起,我不确定最好的主意是什么。嗯,所以我猜使用ObjectSpace是不可能的-这真的是这里要学的课程吗?我想知道…@AmitErandole-您可以在
    项目
    类上定义一个
    终结器
    ,当您执行
    ObjectSpace.garbage\u collect
    时将调用它。但是实现实际上是由一个事实驱动的——你是需要通过你的规范,还是需要实现对上下文严格要求?我想这两者都需要。但我现在想知道的是,我是否应该首先使用
    ObjectSpace
    。让我看看如何使用定稿人,为什么这个问题仅仅因为为了简洁而被编辑就被否决了?你最初提出的问题是一道“代码墙”,很可能会被关闭为“过于本地化”。提出好的问题需要将你的问题浓缩到本质,并确保该问题也与将军未来的来访者相关