【问题标题】:RSpec: How to Stub Only One of Multiple Calls to Same MethodRSpec:如何仅存根对同一方法的多个调用之一
【发布时间】:2019-06-08 22:49:33
【问题描述】:

我无法弄清楚如何仅存根对方法的两个调用中的一个。这是一个例子:

class Example
  def self.foo
    { a: YAML.load_file('a.txt'),   # don't stub - let it load
      b: YAML.load_file('b.txt') }  # stub this one
  end
end

RSpec.describe Example do
  describe '.foo' do
    before do
      allow(YAML).to receive(:load_file).with('b.txt').and_return('b_data')
    end

    it 'returns correct hash' do
      expect(described_class.foo).to eq(a: 'a_data', b: 'b_data')
    end
  end
end

测试失败是因为我使用 args 对第二次调用 ('b.txt') 的调用进行了存根,而不是它遇到的第一次调用 ('a.txt')。我认为参数匹配可以解决这个问题,但它没有。

Failures:

  1) Example.foo returns correct hash
     Failure/Error:
       { a: YAML.load_file('a.txt'),
         b: YAML.load_file('b.txt') }

       Psych received :load_file with unexpected arguments
         expected: ("b.txt")
              got: ("a.txt")
        Please stub a default value first if message might be received with other args as well.  

有没有一种方法可以让第一次呼叫YAML.load_file 通过,但只保留第二次呼叫?我该怎么做?

【问题讨论】:

  • 永远弄清楚为什么allow(YAML).to receive(:load_file).with('b.txt').and_return('b_data') 没有像您期望的那样隔离。我也有同样的期望,and_call_original 也为我解决了这个问题。

标签: ruby unit-testing rspec


【解决方案1】:

有一个and_call_original 选项(请参阅rspec docs)。

应用于您的示例,这应该可以满足您的需求:

before do
  allow(YAML).to receive(:load_file).and_call_original
  allow(YAML).to receive(:load_file).with('b.txt').and_return('b_data')
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2013-03-14
    • 2021-03-15
    • 2015-08-31
    相关资源
    最近更新 更多