【发布时间】:2015-06-09 08:16:03
【问题描述】:
在使用rspec-rails 测试的Rails 4.2.0 应用程序中,我提供了一个JSON Web API,它带有一个带有强制属性mand_attr 的类似REST 的资源。
当 POST 请求中缺少该属性时,我想测试此 API 是否以 HTTP 代码 400 (BAD REQUEST) 回答。(参见第二个示例。)我的控制器尝试通过抛出 ActionController::ParameterMissing 来触发这个 HTTP 代码,如下面的第一个 RSpec 示例所示。
在 其他 RSpec 示例中,我希望引发的异常被示例拯救(如果它们是预期的)或命中测试运行器,因此它们会显示给开发人员(如果错误是意外的),因此我不想删除
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
来自config/environments/test.rb。
我的计划是在request spec 中包含以下内容:
describe 'POST' do
let(:perform_request) { post '/my/api/my_ressource', request_body, request_header }
let(:request_header) { { 'CONTENT_TYPE' => 'application/json' } }
context 'without mandatory attribute' do
let(:request_body) do
{}.to_json
end
it 'raises a ParameterMissing error' do
expect { perform_request }.to raise_error ActionController::ParameterMissing,
'param is missing or the value is empty: mand_attr'
end
context 'in production' do
###############################################################
# How do I make this work without breaking the example above? #
###############################################################
it 'reports BAD REQUEST (HTTP status 400)' do
perform_request
expect(response).to be_a_bad_request
# Above matcher provided by api-matchers. Expectation equivalent to
# expect(response.status).to eq 400
end
end
end
# Below are the examples for the happy path.
# They're not relevant to this question, but I thought
# I'd let you see them for context and illustration.
context 'with mandatory attribute' do
let(:request_body) do
{ mand_attr: 'something' }.to_json
end
it 'creates a ressource entry' do
expect { perform_request }.to change(MyRessource, :count).by 1
end
it 'reports that a ressource entry was created (HTTP status 201)' do
perform_request
expect(response).to create_resource
# Above matcher provided by api-matchers. Expectation equivalent to
# expect(response.status).to eq 201
end
end
end
我找到了两个可行的解决方案和一个部分可行的解决方案,我将把它们作为答案发布。但我对它们中的任何一个都不是特别满意,所以如果你能想出更好(或只是不同)的东西,我想看看你的方法!另外,如果请求规范是测试的规格类型错误,我想知道。
我预见到了这个问题
您为什么要测试 Rails 框架而不仅仅是您的 Rails 应用程序? Rails 框架有自己的测试!
所以让我先发制人地回答这个问题:我觉得我不是在这里测试框架本身,而是我是否正确使用框架。我的控制器不是从 ActionController::Base 继承的,而是从 ActionController::API 继承的,我不知道 ActionController::API 是否默认使用 ActionDispatch::ExceptionWrapper,或者我是否必须首先告诉我的控制器以某种方式这样做。
【问题讨论】:
标签: ruby-on-rails ruby rspec rspec-rails actiondispatch