Reputation: 1814
I have a custom validation that checks whether a param is valid JSON or not:
def is_valid_json
begin
!!JSON.parse(preferences)
rescue
errors.add(:preferences, "This is not valid JSON")
end
end
In my controller test, I want to make sure that when I send in a bad value, the status code of the response is 422. Here is the spec from my controller:
it 'should return a 422 when validations fail' do
put :update, {:user_preferences => { :email => @email, :preferences => 'badval' } }
expect(response.status).to eq(422)
res = JSON.parse(response.body)
expect(res['error']).to_not be_blank
end
The test fails due to an error:
Failure/Error: put :update, {:user_preferences => { :email => @email, :preferences => 'badval' } }
ActiveRecord::RecordInvalid:
Validation failed: Preferences This is not valid JSON
Controller code:
def update
@user_preference = UserPreference.where(email: params[:user_preferences][:email]).first
authorize! :update, @user_preference
@user_preference.update_attributes!(params[:user_preferences])
render_api_response(@user_preference)
end
When I make the request from the browser, I get a 422 return status code, so is there a reason that I can't get the same result from the test?
Upvotes: 0
Views: 75
Reputation: 8295
The way I see it, update_attributes
raises an exception, and you need to catch that. Perhaps you are doing an XHR call with your browser and you code handles that exception code (422) in the front end. For tests to work you should rescue the exception and respond with the relevant status in your render
rescue ActiveRecord::RecordInvalid do
render json: {
error: "Invalid params",
status: 422
},
status: 422
end
Upvotes: 1