故意在Sinatra中引发500个错误,以测试其处理方式

时间:2019-06-15 22:10:02

标签: ruby rspec sinatra rack

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

{
  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错误?

2 个答案:

答案 0 :(得分:1)

面对这样的情况时,我通常要做的是单独的关注点,然后将逻辑移到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

答案 1 :(得分:0)

使用halt方法:

require 'sinatra'

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