【问题标题】:Ruby/Rspec: Possible to compare the content of two objects?Ruby/Rspec:可以比较两个对象的内容吗?
【发布时间】:2012-12-16 05:17:01
【问题描述】:

我在 ruby​​ 中创建了 2 个具有完全相同属性和值的不同对象。

我现在想比较一下两个对象的内容是一样的,但比较如下:

actual.should == expected
actual.should eq(expected)
actual.should (be expected)

失败:

  Diff:
  @@ -1,4 +1,4 @@
  -#<Station:0x2807628
  +#<Station:0x2807610

rspec/ruby 中有什么方法可以轻松实现这一点吗?

干杯!!

【问题讨论】:

    标签: ruby rspec


    【解决方案1】:

    执行此操作的惯用方法是覆盖 #== 运算符:

    class Station
      def ==(o)
        primary_key == o.primary_key
      end
    
      def hash
        primary_key.hash
      end
    end
    

    执行此操作时,您通常还希望覆盖 #hash 方法。覆盖#eql?#equal? 不太常见。

    编辑:在这种特定情况下,您可以做的另一件事是创建一个custom RSpec matcher,而不涉及覆盖#==

    【讨论】:

    • 您好埃里克,感谢您的回答,试图了解这种方法。为什么我们需要覆盖#hash,什么时候会被调用?一旦实现,我们应该如何进行这种比较,比如station_one.==(station_two)
    • @mickael:没问题。您需要覆盖#hash,以便当您将其用作 Hash 对象中的键时,该对象的行为仍然有意义。您只需在 it 块或类似块中执行 obj1.should == obj2 即可在 Rspec 中使用覆盖的 #== 运算符。
    【解决方案2】:

    使用 have_attributes 匹配器指定对象的属性与预期的属性匹配:

      Person = Struct.new(:name, :age)
      person = Person.new("Jim", 32)
    
      expect(person).to have_attributes(:name => "Jim", :age => 32)
      expect(person).to have_attributes(:name => a_string_starting_with("J"), :age => (a_value > 30) )
    

    Relishapp RSpec Docs

    【讨论】:

      【解决方案3】:

      有点晚了,但你可以序列化它,例如:

      require 'json'
      
      expect(actual.to_json).to eq(expected.to_json) #new rspec syntax
      actual.to_json.should eq(expected.to_json) #old rspec syntax
      

      【讨论】:

        【解决方案4】:

        也许您应该考虑在对象上重载等于运算符。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-07
          • 2015-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-21
          • 1970-01-01
          相关资源
          最近更新 更多