我正在使用Rails 4.2.5
,并试图在请求格式错误的情况下测试来自控制器的预期400响应。参数验证逻辑由strong_parameters
处理。
上下文
在我的控制器中,我有:
def user_params
params.require(:user).permit(:foo, :bar, :baz)
end
我在POST请求中引用了user_params
,其中Accept
和ContentType
标头设置为application/json
。
在development
中,没有user
参数的POSTing将引发ActionController::ParameterMissing
异常
如果我在environments/development.rb
文件中设置了这个:
Rails.application.configure do
config.consider_all_requests_local = false
end
Rails的行为与production
类似,并返回一个简单的400响应,而不是调试页面。太棒了
问题
不过,我在控制器测试中遇到了同样的问题(rspec-rails ~> 3.4
)。
具体来说,这将通过:
expect {
post :action, malformed_params
}.to raise_error(ActionController::ParameterMissing)
但这不会是因为引发了一个异常:
post :action, malformed_params
expect(response.status).to eql 400
我已经尝试过为测试环境翻转consider_all_requests_local
,但没有成功。
有什么解决方案吗?关于这个问题,有一个古老的答案,但它没有帮助(甚至询问者也意识到它没有用处)。
编辑:
正如评论中所要求的,以下是控制器规范中的参数:
let(:user_data) do
{ foo: "foo", bar: "bar", baz: "baz" }
end
let(:good_params) do
{
some_id: SecureRandom.uuid,
user: user_data
}
end
let(:malformed_params) do
{ some_id: SecureRandom.uuid }.merge(user_data)
end
let(:incomplete_params) do
{ some_id: SecureRandom.uuid }
end
good_params
适用于快乐之路。当我想测试400时,malformed_params
和incomplete_params
都不起作用:两者都会引发异常并导致测试失败。
我已经验证了在POST到正在运行的服务器时,相同的参数有效载荷将起作用(在development
中,但如上所述对配置进行了调整)。
如果您想模拟所有环境中的生产,并在缺少任何所需参数时始终引发400,而不是更改每个配置文件,您可以只放入控制器(或ApplicationController
或任何其他混合元素,使其更通用):
# assuming we're talking about a JSON API
rescue_from ActionController::ParameterMissing do |e|
render json: { error: e.message }, status: :bad_request
end
# or more general for any kind of response
rescue_from ActionController::ParameterMissing do |e|
head :bad_request
end
引发的异常是正确的,因为没有发送格式错误的json。有效负载的格式很好,但缺少一个params。
你必须尝试类似的东西:
'{ i am malformed json'