RSpec重试抛出异常,然后返回值
我有一个重试块
 def my_method
    app_instances = []
    attempts = 0
    begin 
      app_instances = fetch_and_rescan_app_instances(page_n, policy_id, policy_cpath)
    rescue Exception
      attempts += 1
      retry unless attempts > 2
      raise Exception 
    end
    page_n += 1
  end
  fetch_and_rescan_app_instances访问网络可能会引发异常。 
我想写一个rspec测试,它第一次抛出一个异常,并且不会在第二次被调用时抛出异常,所以我可以测试第二次抛出异常时,my_method不会抛出异常exeption。
  我知道我可以做stub(:fetch_and_rescan_app_instances).and_return(1,3) ,第一次它返回1和第二次3,但我不知道如何做第一次抛出异常和第二次返回的东西。 
您可以计算块中的返回值:
describe "my_method" do
  before do
    my_instance = ...
    @times_called = 0
    my_instance.stub(:fetch_and_rescan_app_instances).and_return do
      @times_called += 1
      raise Exception if @times_called == 1
    end
  end
  it "raises exception first time method is called" do
    my_instance.my_method().should raise_exception
  end
  it "does not raise an exception the second time method is called" do
    begin
      my_instance.my_method()
    rescue Exception
    end
    my_instance.my_method().should_not raise_exception
  end
end
  请注意,你实际上不应该从Exception拯救,使用更具体的东西。  请参阅:为什么在Ruby中拯救Exception => e`是一种糟糕的风格? 
你所做的是约束信息应该被接收的时间(接收次数),即在你的情况下你可以
instance.stub(:fetch_and_rescan_app_instances).once.and_raise(RuntimeError, 'fail')
instance.stub(:fetch_and_rescan_app_instances).once.and_return('some return value')
  第一次调用instance.fetch_and_rescan_app_instances将引发RuntimeError,第二次将返回“某些返回值”。 
PS。 调用比这更多将导致错误,您可能会考虑使用不同的接收计数规范https://www.relishapp.com/rspec/rspec-mocks/docs/message-expectations/receive-counts
  这在RSpec3.x中稍有改变。  看来最好的方法是将块传递给定义此类行为的receive 。 
以下是来自文档建议如何创建这种类型的运输失败:
(这个错误每隔一次被称为...但很容易适应。)
RSpec.describe "An HTTP API client" do
  it "can simulate transient network failures" do
    client = double("MyHTTPClient")
    call_count = 0
    allow(client).to receive(:fetch_data) do
      call_count += 1
      call_count.odd? ? raise("timeout") : { :count => 15 }
    end
    expect { client.fetch_data }.to raise_error("timeout")
    expect(client.fetch_data).to eq(:count => 15)
    expect { client.fetch_data }.to raise_error("timeout")
    expect(client.fetch_data).to eq(:count => 15)
  end
end
                        链接地址: http://www.djcxy.com/p/25853.html
                        
                        
                    