【问题标题】:How can I test an action that handles exceptions using rack/test on Sinatra?如何在 Sinatra 上使用 rack/test 测试处理异常的操作?
【发布时间】:2011-08-26 17:29:06
【问题描述】:

我想测试我在 Sinatra 上制作的这条路线:

get '/party' do
  begin
    party_source.parties
  rescue Exceptions::SourceNotFoundError
    status 404
  rescue Exceptions::SourceInternalError
    status 503
  end
end

我编写了这个测试(假设测试可以访问party_source,在实际代码中是这样):

require 'rack/test'
def test_correct_status_code_when_get_error_404
    source_404 = mock() 
    source_404.expects(:parties).with(nil).raises(Exceptions::SourceNotFoundError)
    MyApp.party_source = source_404 

    get '/party'
    assert_equal 404, last_response.status
end

当我运行此测试时,它失败了,因为我没有得到 404(我的代码),而是得到状态 500。无论我提出什么异常,我总是得到状态 500,我认为这是由 Sinatra 或 Rack 生成的。

我该如何测试这个案例?

更新

据我所知,异常并没有被我的救援块捕获。 Rack 或 Sinatra 正在获取它并处理 HTTP 状态 500 响应消息。

我无法理解我的救援代码块是如何被忽略的。

【问题讨论】:

  • 那么我要测试的是不常见的吗? 5天内没有答案。有什么我可以更好地解释的吗?
  • 不是没有捕获到异常,而是你只捕获了两类异常。使用rescue Exception 在开始/救援块的末尾添加一个总称,您将很快发现问题出在哪里。
  • 你好 Benoit,你是对的。问题是模拟对象引发了另一个异常。如果您想发布答案,我可以将其标记为正确。谢谢!
  • 完成,我编辑了我之前的答案。谢谢!

标签: ruby unit-testing sinatra rack


【解决方案1】:

这是一个简短的示例,表明您可以测试这样的操作:

hello_sinatra.rb:

require 'sinatra/base'

class Hello < Sinatra::Base
  get '/party' do
    begin
      raise StandardError
    rescue StandardError
      status 404
    end
  end
end


Hello.run! if __FILE__ == $0

sinatra_test.rb:

$:.push('.')
require 'hello_sinatra'
require 'test/unit'
require 'rack/test'

ENV['RACK_ENV'] = 'test'

class HelloTest < Test::Unit::TestCase
  include Rack::Test::Methods

  def app
    Hello
  end

  def test_correct_status_code_when_get_error_404
    get '/party'
    assert_equal 404, last_response.status
  end
end

但是,您的代码中有些地方看起来很奇怪。你能不能试着用app.party_source = source_404替换MyApp.party_source = source_404

更新

您只捕获了 Exceptions::SourceNotFoundError 和 Exceptions::SourceInternalError,您的模拟中可能出现了其他问题,这会导致 500 错误。

使用rescue Exception 在开始/救援块的末尾添加一个总称,您将很快发现问题出在哪里。

【讨论】:

  • 关于 MyApp.party_source 我没有使用 Sinatra::Base 所以我用 def self.party_souce (..) 创建了一个 MyApp 类,所以我可以在我的测试中设置 party_source 变量。跨度>
  • 如果我将 raise 放在 begin..rescue 块内,它就可以工作。但是当模拟对象引发错误时,救援块不会被执行。有任何想法吗?我正在使用摩卡咖啡
猜你喜欢
  • 2013-09-01
  • 2012-02-19
  • 2015-12-12
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
  • 1970-01-01
相关资源
最近更新 更多