Ruby on rails rspec:如何在引发错误后测试确保块

Ruby on rails rspec:如何在引发错误后测试确保块,ruby-on-rails,ruby,rspec,Ruby On Rails,Ruby,Rspec,这是我的begin..rescue..sureblock。我想编写一些测试用例,在出现错误后,将返回最终结果{}。 我使用的是rspec3.3 def external_call result = ExternalApi.call rescue => e # handle the error, and re-raise Handler.handle(e) raise ensure result.presence || {} end 我已经为rescue部分编写了测试

这是我的
begin..rescue..sure
block。我想编写一些测试用例,在出现错误后,将返回最终结果
{}
。 我使用的是rspec3.3

def external_call
  result = ExternalApi.call 
rescue => e
  # handle the error, and re-raise
  Handler.handle(e)
  raise
ensure
  result.presence || {}
end
我已经为rescue部分编写了测试用例:

context 'when external api raise error' do
  it 'handles the error, and re-raise' do
    allow(ExternalApi).to receive(:call).and_raise(SomeError)
    expect(Handler).to receive(:handle).with(e)
    expect { subject.external_call }.to raise_error(SomeError)
  end
end
但我不确定在错误再次出现后如何测试确保部分。 以下是我的尝试:

  it 'returns {} after error raised' do
    allow(ExternalApi).to receive(:call).and_raise(SomeError)
    result = subject.external_call
    expect(result).to eq({})
  end

在这种情况下,测试用例将在
subject.external\u call
行失败,因为它将在那里引发错误。我不确定在重新引发错误后如何测试这种情况。

当使用带有隐式返回的begin/rescue/sure块时,ruby将返回在rescue块中运行的最后一个方法作为返回值,而不是sure。如果需要返回来自“确保”块的值,则必须显式返回该值,或者不包括在“确保”中,而是移动到“开始/救援”块之外

下面是一个显示差异的示例

class TestClass

  def self.method1
    raise 'an error'
  rescue
    'rescue block'
  ensure
    'ensure block'
  end

  def self.method2
    raise 'an error'
  rescue
    'rescue block'
  ensure
    return 'ensure block'
  end

  def self.method3
    begin
      raise 'an error'
    rescue
      'rescue block'
    end
    'ensure equivalent block'
  end
end

RSpec.describe TestClass do
  it do
    # does not work, method1 returns 'rescue block'
    expect(TestClass.method1).to eql 'ensure block'
  end

  it do
    # does work, as method2 explicitly returns 'ensure block'
    expect(TestClass.method2).to eql 'ensure block'
  end

  it do
    # does work, as method3 uses 'ensure equivalent block' as the inferred return
    expect(TestClass.method3).to eql 'ensure equivalent block'
  end
end

感谢您的澄清,我将把返回结果移出确保块。
def self.method1引发“一个错误”rescue LOgger.error“一些”确保返回“确保块”结束
将返回记录器的结果。error=>true