RSpec: How to Stub Only One of Multiple Calls to Same Method

故事扮演 提交于 2020-03-23 12:40:31

问题


I'm having trouble figuring out how to stub only one of two calls to a method. Here's an example:

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

The test fails because I have stubbed a call to YAML.load_file with the args for the second call ('b.txt'), not the first one it encounters('a.txt'). I thought argument matching would address this but it does not.

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.  

Is there a way I can allow the first call to YAML.load_file to go through but only stub the second call? How would I do this?


回答1:


There is a and_call_original option (see rspec docs).

Applied to your example, this should do what you are looking for:

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


来源:https://stackoverflow.com/questions/54190150/rspec-how-to-stub-only-one-of-multiple-calls-to-same-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!