故意在Sinatra中提出500个错误,以测试如何处理它们



我想编写一个 RSpec 测试来验证,如果我的 Sinatra 驱动的 API 中发生 500 错误,该错误将被 Sinatra error 定义捕获并以 JSON 格式返回给客户端。也就是说,它不会返回一些 HTML 错误页面,而是返回如下 JSON 以符合 API 的其余部分:

{
  success: "false",
  response: "Internal server error"
}

但是,我不确定如何在我的 Sinatra 应用程序中实际触发 500 错误,以便使用 RSpec 测试此行为。我找不到模拟Sinatra路线的方法,所以目前我最好的主意是这条故意导致500的路线。这感觉像是一个非常可怕的解决方案:

get '/api/v1/testing/internal-server-error' do
  1 / 0
end

有没有办法模拟Sinatra路由,以便我可以让/的路由处理程序块引发异常,从而触发500?如果没有,是否有其他方法故意在我的应用程序中造成 500 错误?

当面对这样的情况时,我通常做的是分开关注点,并将逻辑移出Sinatra get ...块。然后,很容易将其存根并使其引发错误。

例如,给定以下服务器代码:

# server.rb
require 'sinatra'
class SomeModel
  def self.some_action
    "do what you need to do"
  end
end
get '/' do
  SomeModel.some_action
end

然后,您可以使用此代码使模型或用于实际生成响应的任何其他类/函数引发错误,使用以下规范:

# spec
describe '/' do
  context 'on error' do
    before do 
      allow(SomeModel).to receive(:some_action) { raise ArgumentError }
    end
    it 'errors gracefully' do
      get '/'
      expect(last_response.status).to eq 500
    end
  end
end

为了完整起见,下面是一个自包含的文件,可以通过运行rspec thisfile.rb来测试以演示此方法:

# thisfile.rb
require 'rack/test'
require 'rspec'
require 'sinatra'
# server
class SomeModel
  def self.some_action
    "do what you need to do"
  end
end
get '/' do
  SomeModel.some_action
end
# spec_helper
ENV['APP_ENV'] = 'test'
module RSpecMixin
  include Rack::Test::Methods
  def app() Sinatra::Application end
end
RSpec.configure do |c|
  c.include RSpecMixin
end
# spec
describe '/' do
  context 'on error' do
    before do 
      allow(SomeModel).to receive(:some_action) { raise ArgumentError }
    end
    it 'errors gracefully' do
      get '/'
      expect(last_response.status).to eq 500
    end
  end
end

使用 halt 方法:

require 'sinatra'
get '/' do
  halt 500, {
    success: 'false',
    response: 'Internal server error'
  }.to_json
end

最新更新