Ruby-on-rails 如何在 RSpec 中使用 HTTP 状态代码符号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18274709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use HTTP status code symbols in RSpec?
提问by JJD
I use HTTP status code symbolsin code in a controller such as:
我在控制器的代码中使用HTTP 状态代码符号,例如:
render json: {
auth_token: user.authentication_token,
user: user
},
status: :created
or
或者
render json: {
errors: ["Missing parameter."]
},
success: false,
status: :unprocessable_entity
In the code of my request spec I also would like to use the symbols:
在我的请求规范的代码中,我还想使用以下符号:
post user_session_path, email: @user.email, password: @user.password
expect(last_response.status).to eq(201)
...
...
expect(last_response.status).to eq(422)
However each test where I use the symbols instead of integers fails:
但是,我使用符号而不是整数的每个测试都失败了:
Failure/Error: expect(last_response.status).to eq(:created)
expected: :created
got: 201
(compared using ==)
Here is the latest list of HTTP status code symbols in Rack.
这是Rack中HTTP 状态代码符号的最新列表。
采纳答案by apneadiving
On the one hand, response is built with methods like:
一方面,响应是使用以下方法构建的:
success?
redirect?
unprocessable?
full list do:
response.methods.grep(/\?/)
成功?
重定向?
无法处理?
完整列表做:
response.methods.grep(/\?/)
On the other hand, Rspec predicates transforms every foo?method to a be_foomatcher.
另一方面,Rspec 谓词将每个foo?方法转换为be_foo匹配器。
Not sure you can have the 201 this way unfortunately, but creating a custom matcher is quite easy.
不幸的是,不确定您是否可以通过这种方式使用 201,但是创建自定义匹配器非常容易。
Note Rails test only rely on a few statuses.
注意 Rails 测试只依赖于几个状态。
回答by Aaron K
The responseobject responds to several of the symbol types as messages. So you can simply do:
该response对象将几种符号类型作为消息进行响应。所以你可以简单地做:
expect(response).to be_success
expect(response).to be_error
expect(response).to be_missing
expect(response).to be_redirect
For the other types, such as :created, you can create a simple custom matcher for this which wraps assert_response:
对于其他类型,例如:created,您可以为此创建一个简单的自定义匹配器,其中包含assert_response:
RSpec::Matchers.define :have_status do |type, message = nil|
match do |_response|
assert_response type, message
end
end
expect(response).to have_status(:created)
expect(response).to have_status(404)
This should work fine for controller specs which have the proper state setup. It will notwork for feature specs. I haven't tried with request specs, so your milage may vary there.
这对于具有正确状态设置的控制器规格应该可以正常工作。它不适用于功能规格。我还没有尝试过请求规格,所以你的里程可能会有所不同。
The reason this works is it leverages the fact that RSpec controller specs have similar state setup behind the scenes. So when assert_responseaccesses @responseit is available.
这样做的原因是它利用了 RSpec 控制器规范在幕后具有类似状态设置的事实。所以当assert_response访问@response它是可用的。
This matcher can probably be improved by simply copying the code used by assert_responseinto the matcher:
这个匹配器可能可以通过简单地将使用的代码复制到匹配器中来改进assert_response:
RSpec::Matchers.define :have_status do |type, message = nil|
match do |response|
if Symbol === type
if [:success, :missing, :redirect, :error].include?(type)
response.send("#{type}?")
else
code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
response.response_code == code
end
else
response.response_code == type
end
end
failure_message do |response|
message or
"Expected response to be a <#{type}>, but was <#{response.response_code}>"
end
end
UPDATE: 2014-07-02
更新:2014-07-02
This is now available out of the box with RSpec Rails 3: https://www.relishapp.com/rspec/rspec-rails/v/3-0/docs/matchers/have-http-status-matcher
现在可以使用 RSpec Rails 3 开箱即用:https: //www.relishapp.com/rspec/rspec-rails/v/3-0/docs/matchers/have-http-status-matcher
回答by cyrilchampier
this works for me:
这对我有用:
expect(response.response_code).to eq(Rack::Utils::SYMBOL_TO_STATUS_CODE[:not_found])
回答by schmijos
With rspec-rails(as of rspec3) it's possible to use
使用rspec-rails(从rspec3 开始),可以使用
expect(response).to have_http_status(:created)
Update 2018-06-11:
2018-06-11 更新:
As of Rails 6, some of the matchers will be replaced (e. g. successby successful).
从 Rails 6 开始,一些匹配器将被替换(例如success由successful)。

