我想编写一个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错误?
答案 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