【问题标题】:RSpec: How to compare have_received arguments by object identity?RSpec:如何按对象身份比较 have_received 参数?
【发布时间】:2021-10-12 03:30:48
【问题描述】:

我曾经使用expect(subject/double).to haved_received(:a_method).with(args).exactly(n).times 来测试一个方法是否被一些特定的参数调用并且被准确地调用了 {n} 次。但是今天它的参数是Comparable对象,看看下面的代码:

设置

class A; end

class B
 include Comparable
 attr_reader :val

 def initialize(val)
   @val = val
 end

 def <=>(other)
   self.val <=> other.val
 end
end

class S
 def call(x); end
end

s = S.new
allow(s).to receive(:call)

现在下面的测试通过了普通对象 A

a1 = A.new
a2 = A.new

s.call(a1)
s.call(a2)

expect(s).to have_received(:call).with(a1).exactly(1).times
expect(s).to have_received(:call).with(a2).exactly(1).times

但它失败了 Comparable 对象 B

b1 = B.new(0)
b2 = B.new(0)

s.call(b1)
s.call(b2)

expect(s).to have_received(:call).with(b1).exactly(1).times
expect(s).to have_received(:call).with(b2).exactly(1).times

我调试并看到rspec匹配器调用宇宙飞船运算符&lt;=&gt;来验证参数,所以它认为b1和b2是相同的

Failure/Error: expect(s).to have_received(:call).with(b1).exactly(1).times
expected: 1 time with arguments:
received: 2 times with arguments:

我应该怎么做才能通过测试?

【问题讨论】:

    标签: ruby rspec object-identity


    【解决方案1】:

    发生这种情况是因为Comparable 实现了==,因此您的对象被视为与== 相等:

    b1 = B.new(0)
    b2 = B.new(0)
    
    b1 == b2 #=> true
    

    要根据对象身份设置约束,您可以使用equal 匹配器:(或其别名an_object_equal_to / equal_to

    expect(s).to have_received(:call).with(an_object_equal_to(b1)).once
    

    在后台,这个匹配器调用equal?

    b1 = B.new(0)
    b2 = B.new(0)
    
    b1.equal?(b2) #=> false
    

    【讨论】:

      【解决方案2】:

      我的解决方案:使用the have_attributes matcher 准确检查对象参数的object_id

      expect(s).to have_received(:call).with(have_attributes(object_id: b1.object_id))
      .exactly(1).times
      
      expect(s).to have_received(:call).with(have_attributes(object_id: b2.object_id))
      .exactly(1).times
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-21
        • 2016-10-02
        • 1970-01-01
        • 1970-01-01
        • 2015-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多