das*_*s-g 19 ruby rspec ruby-on-rails rspec-rails actiondispatch
在测试的Rails 4.2.0应用程序中rspec-rails,我提供了一个JSON Web API,它具有类似REST的资源,具有强制属性mand_attr.
我想测试一下,BAD REQUEST当POST请求中缺少该属性时,此API会回答HTTP代码400().(请参阅第二个示例.)我的控制器尝试通过抛出一个来生成此HTTP代码ActionController::ParameterMissing,如下面的第一个RSpec示例所示.
在其他 RSpec示例中,我希望通过示例(如果它们是预期的)挽救引发的异常或者命中测试运行器,因此它们会显示给开发人员(如果错误是意外的),因此我不想要去除
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
Run Code Online (Sandbox Code Playgroud)
来自config/environments/test.rb.
我的计划是在请求规范中包含以下内容:
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
Run Code Online (Sandbox Code Playgroud)
我找到了两个工作和一个部分工作的解决方案,我将作为答案发布.但我对他们中的任何一个都不是特别满意,所以如果你能想出更好的东西(或者只是不同的东西),我希望看到你的方法!另外,如果请求规范是错误的规范类型来测试它,我想知道.
我预见到了这个问题
所以让我先发制人地回答:我觉得我不是在这里测试框架,而是我是否正确使用框架.我的控制器不继承,ActionController::Base但ActionController::API我不知道是否默认ActionController::API使用ActionDispatch::ExceptionWrapper,或者我是否必须告诉我的控制器以某种方式这样做.
您想为此使用RSpec筛选器。如果以这种方式进行,则对的修改Rails.application.config.action_dispatch.show_exceptions将是示例的本地操作,并且不会干扰您的其他测试:
# This configure block can be moved into a spec helper
RSpec.configure do |config|
config.before(:example, exceptions: :catch) do
allow(Rails.application.config.action_dispatch).to receive(:show_exceptions) { true }
end
end
RSpec.describe 'POST' do
let(:perform_request) { post '/my/api/my_ressource', request_body }
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
end
context 'in production', exceptions: :catch do
it 'reports BAD REQUEST (HTTP status 400)' do
perform_request
expect(response).to be_a_bad_request
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
该exceptions: :catch是RSpec的发言“任意元数据”,我这里选择的命名是为了便于阅读。
nil从部分模拟的应用程序配置返回
context 'in production' do
before do
allow(Rails.application.config.action_dispatch).to receive(:show_exceptions)
end
it 'reports BAD REQUEST (HTTP status 400)' do
perform_request
expect(response).to be_a_bad_request
end
end
Run Code Online (Sandbox Code Playgroud)
或者更明确地使用
context 'in production' do
before do
allow(Rails.application.config.action_dispatch).to receive(:show_exceptions).and_return nil
end
it 'reports BAD REQUEST (HTTP status 400)' do
perform_request
expect(response).to be_a_bad_request
end
end
Run Code Online (Sandbox Code Playgroud)
如果这是唯一正在运行的示例,则可以工作。但如果是的话,我们也可以从 中删除该设置config/environments/test.rb,所以这有点没有实际意义。当有多个示例时,这将不起作用,因为Rails.application.env_config()查询此设置并缓存其结果。
| 归档时间: |
|
| 查看次数: |
4401 次 |
| 最近记录: |