I'm working with Rails 4.2.5
, and I'm trying to test an expected 400 response from a controller in case of malformed request. The parameter validation logic is handled by strong_parameters
.
the context
In my controller I have:
def user_params
params.require(:user).permit(:foo, :bar, :baz)
end
And I'm referencing user_params
in a POST request with Accept
and ContentType
headers set to application/json
.
In development
, POSTing without a user
parameter will raise a ActionController::ParameterMissing
exception.
If I set this in my environments/development.rb
file:
Rails.application.configure do
config.consider_all_requests_local = false
end
Rails will act like in production
and return a simple 400 response instead of the debug page. Great.
the problem
I'm having troubles doing the same thing in my controller tests, though (rspec-rails ~> 3.4
).
Specifically, this will pass:
expect {
post :action, malformed_params
}.to raise_error(ActionController::ParameterMissing)
but this won't because of the raised exception:
post :action, malformed_params
expect(response.status).to eql 400
I have already tried to flip the consider_all_requests_local
for the test environment, to no avail.
Any solution? There is an old answer on this, but it does not help (and even the asker recognized it was not useful).
Edit:
As asked in the comments, here are the parameters from the controller spec:
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
works for the happy path. Neither malformed_params
nor incomplete_params
work when I want to test the 400: both will raise the exception and cause the test to fail.
I've already verified that the same parameter payloads will work when POSTing to a running server (in development
, but with the configuration tweaked as described above).