我希望将前两次调用带有引发异常的HTTParty,然后第三次调用应该返回值。
before do
allow(HTTParty).to receive(:get).exactly(2).times.with(url).and_raise(HTTParty::Error)
allow(HTTParty).to receive(:get).with(url).and_return('{}')
end
但允许覆盖另一个。如何设置存根以在前几次尝试时引发错误,然后让它返回一个值?
答案 0 :(得分:6)
根据this github issue中提供的信息,您也可以使用以下纯RSpec方法执行此操作。它利用了定义模拟响应的最常用方式using block :
before do
reponse_values = [:raise, :raise, '{}']
allow(HTTParty).to receive(:get).exactly(3).times.with(url) do
v = response_values.shift
v == :raise ? raise(HTTParty::Error) : v
end
end
答案 1 :(得分:1)
在这种特定情况下,您可以使用WebMock:
Multiple responses using chained
to_return()
,to_raise()
orto_timeout
declarations。
这样的事情应该有效:
before do
stub_request(:get, url).
to_raise(SomeException).then.
to_raise(SomeException).then.
to_return(body: '{}')
end
SomeException
应该是实际的网络错误。
答案 2 :(得分:0)
您可以使用Proc
实例数组来完全控制:
my_object = double
values = [proc { raise ArgumentError }, proc { 2 }]
allow(my_object).to receive(:my_method).exactly(:twice) { values.shift.call }
expect { my_object.my_method }.to raise_error ArgumentError
expect(my_object.my_method).to eq 2
这样,您可以在多个调用中引发不同的异常,或者仅返回满足您需求的值。
当所有已存根的响应都用完后,您可以使用类似的方法来调用原始文件:
allow(my_object).to receive(:my_method).and_wrap_original do |original, *args|
values.empty? ? original.call(*args) : values.shift.call
end