【问题标题】:Testing methods that eventually throw an exception in RSpec最终在 RSpec 中抛出异常的测试方法
【发布时间】:2018-05-19 15:28:49
【问题描述】:

我有一个方法如下:

 if response.fetch('ok')
    response.fetch(response_key) { [] }
  elsif response.fetch('error') == 'token_revoked'
    ErrorReporter.increment('access_revoked', source: { account_id: account_id }, sporadic: true)
    fail(RemoteService::AccessRevoked, 'Our access to your account was revoked, please re-authorize.')
  else
    ErrorReporter.increment(
      'bad_request',
      source: {
        account_id: account_id
        error: response.fetch('error')
      },
      sporadic: true
    )
    fail(RemoteService::InvalidRequest, 'Something went wrong communicating with the remote service, please try again')
  end

当请求返回 token_revoked 错误时,我正在尝试测试场景。我想确保测试指定在这种情况下,我们将错误报告给我们的 ErrorReporting 服务。

所以,我的规范看起来像这样:

it 'records the failure with our error reporting service' do
  expect(ErrorReporter).to receive(:increment).with(
    'bad_request',
     source: {
       account_id:  1
     },
     sporadic: true
   )

   available_channels.fetch
end

但是,此规范总是失败,因为在调用 ErrorReporter 后,代码会立即调用 fail,这使我的规范失败。有谁知道如何在处理我知道代码现在将抛出的不可避免的异常时验证对我的错误报告器的调用?

【问题讨论】:

  • 不,这没有帮助,之后的规范处理了我期望抛出异常的事实,在这里我试图断言我们将错误发送到我们的服务 抛出异常之前。
  • 只需将对available_channels.fetch 的调用封装在begin ... rescue RemoteService::InvalidRequest 块中。
  • @Stefan 打败了我

标签: ruby-on-rails ruby rspec exception-handling


【解决方案1】:

您可以expect errors 在代码中提出。为了让 RSpec 捕获异常,您需要使用如下块:

it 'records the failure with our error reporting service' do
  expect(ErrorReporter).to receive(:increment).with(
    'bad_request',
    source: {
      account_id:  1
    },
    sporadic: true
  )

  expect { available_channels.fetch }
    .to raise_error RemoteService::InvalidRequest
end

【讨论】:

  • 是的,这也是我的结论,感谢您确认这种方法可能是处理它的最佳方法。
【解决方案2】:

该异常导致您的示例失败,因为它没有被抢救。为防止错误,您可以将方法调用包装在 begin ... rescue 块中:

it 'records the failure with our error reporting service' do
  expect(ErrorReporter).to receive(:increment).with(
    'bad_request',
     source: {
       account_id:  1
     },
     sporadic: true
   )

   begin
     available_channels.fetch
   rescue => RemoteService::InvalidRequest
     # would cause the example to fail
   end
end

在另一个示例中,您还应该expect 要引发的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多