【问题标题】:Rspec: Test rescue blockRspec:测试救援块
【发布时间】:2012-01-05 14:53:08
【问题描述】:

我有一个这样的块:

begin
  response = Facebook.make_profile_request(params[:token])
rescue => e
  Airbrake.notify(
     :error_class => "Facebook Processing",
     :error_message => "Error: #{e.message}"
   )

  flash[:notice] = "Uh oh...something went wrong. Please try again."
  redirect_to root_path
end

这是我目前所拥有的:

it "should notify Airbrake if call to FB fails" do
  Facebook.stub(:make_profile_request).with(fb_token).and_raise(Exception)
  Airbrake.should_receive(:notify)
  get :facebook_process, token: fb_token
end

我得到错误:

  1) UsersController GET facebook_process should notify Airbrake if call to FB fails
 Failure/Error: get :facebook_process, token: fb_token
 Exception:
   Exception
 # ./app/controllers/users_controller.rb:9:in `facebook_process'
 # ./spec/controllers/users_controller_spec.rb:41:in `block (3 levels) in <top (required)>'

我应该如何正确测试救援?

【问题讨论】:

  • 将您在测试存根中引发的异常更改为 RuntimeError 之类的内容,因为 `rescue' 没有捕捉到它。

标签: ruby-on-rails-3 rspec2 rspec-rails


【解决方案1】:

你必须指定一个特定的异常类,否则rspec一检测到异常就会退出;但是,这就是你如何在不从异常中拯救的情况下做到这一点(正如尼克的评论中所指出的那样)。

class MyCustomError < StandardError; end

begin
  response = Facebook.make_profile_request(params[:token])
rescue MyCustomError => e
  ...
end

在您的规范中,您应该让存根返回自定义错误类。像这样的:

Facebook.stub(:make_profile_request).with(fb_token).and_raise(MyCustomError)

【讨论】:

  • 您还需要更改存根以返回自定义错误类。
  • 不推荐使用来自 rspec-mocks 的旧 :should 语法的 stub 而不显式启用该语法。改用新的:expect 语法或显式启用:should
【解决方案2】:

我最近遇到了类似的问题。

如果你改变你的代码

rescue => e

rescue Exception => e

您的测试用例将通过。

【讨论】:

  • 如果您认为这是个坏主意,欢迎您将好主意作为您的答案。
  • 不幸的是我没有答案。我就是这样来到这里的——寻找解决方案。话虽如此,尽管我没有答案,但值得提醒读者注意不良做法。
  • @Nick 你在你的规范中提高了Exception,这通常不会被rescue 捕获。在规范中提出更具体的内容。
  • @DeanBrundage 请注意,我不是提出这个问题的人,所以这不是我的测试。但是,您提出了一个很好的观点 - 您可以提出一个 RuntimeError,它应该被 rescue 捕获。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-26
  • 2023-01-13
相关资源
最近更新 更多