为什么 rspec 双打收到 :== 两次

Why do rspec doubles receive :== twice

我有一个正在使用的测试意外失败了。它是说 == 被调用了两次。是不是因为它也是方法的参数?

这是我所说内容的提炼示例

require 'rspec'
describe 'rspec test doubles' do
    let(:a_double) { double('a_double') }

    it 'should only call == once' do
        expect(a_double).to receive(:==).and_return(true)
        a_double == a_double
    end
end

这就是我 运行 这个测试

得到的结果
F

Failures:

  1) rspec test doubles should only call == once
     Failure/Error: expect(watir_driver).to receive(:==).and_return(true)
       (Double "watir_driver").==(*(any args))
           expected: 1 time with any arguments
           received: 2 times with any arguments
     # ./double_spec.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.019 seconds (files took 0.26902 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./double_spec.rb:6 # rspec test doubles should only call == once

查看 rspec-mocks 中的 TestDouble class,我们发现:

# This allows for comparing the mock to other objects that proxy such as
# ActiveRecords belongs_to proxy objects. By making the other object run
# the comparison, we're sure the call gets delegated to the proxy
# target.
def ==(other)
  other == __mock_proxy
end

所以看起来 rspec 有意反转调用。假设你有两个独立的双打,做 double_1 == double2 会按照这些行做一些事情:

  • 致电double_1 == double2
  • 正如我们所见,这会反转它,但它会将 double_1 换成 double_1 的代理:double2 == __mock_proxy
  • 然后 double2 将再次调用(otherdouble_1 的代理):other == __mock_proxy.
  • 因为 other 是一个 Proxy 对象而不是 TestDouble,调用了一个不同的 == 方法(此时正在比较两个 Proxy 对象),我们终于得到了比较。

正如您所见,== 实际上在 3 个不同的事物上被调用:第一个替身,第二个替身,最后是第一个替身的代理。因为你的第一个和第二个 double 相同,所以它被调用了两次。

TestDouble's == method and Proxy's == method