Reputation: 25542
Here is my test:
describe "GET show" do
it "assigns service_request as @service_request" do
get :show, { company_id: @company.id, id: service_request.id }
expect(assigns(:service_request)).to eq service_request
end
it "returns 404 when service_request is not found" do
get :show, { company_id: @company.id, id: "foo" }
expect(response.status).to eq 404
end
end
The error in my terminal is:
1) ServiceRequestsController GET show returns 404 when service_request is not found
Failure/Error: get :show, { company_id: @company.id, id: "foo" }
ActiveRecord::RecordNotFound:
Couldn't find ServiceRequest with 'id'=foo [WHERE (company_id IS NOT NULL)]
# ./spec/controllers/service_requests_controller_spec.rb:44:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
Obviously this isn't correct, but I'm not sure what's wrong
Upvotes: 4
Views: 3819
Reputation: 1099
Just had this issue. It turns out that in the test environment, rails shows error messages to help with debugging.
This blog post details a way of getting "production-like" error responses to test your API responses. It recommends creating a helper spec/support/error_responses.rb
:
module ErrorResponses
def respond_without_detailed_exceptions
env_config = Rails.application.env_config
original_show_exceptions = env_config["action_dispatch.show_exceptions"]
original_show_detailed_exceptions = env_config["action_dispatch.show_detailed_exceptions"]
env_config["action_dispatch.show_exceptions"] = true
env_config["action_dispatch.show_detailed_exceptions"] = false
yield
ensure
env_config["action_dispatch.show_exceptions"] = original_show_exceptions
env_config["action_dispatch.show_detailed_exceptions"] = original_show_detailed_exceptions
end
end
RSpec.configure do |config|
config.include ErrorResponses
config.around(realistic_error_responses: true) do |example|
respond_without_detailed_exceptions(&example)
end
end
This can then be used in your case as follows. Note the use of :realistic_error_responses
.
describe "GET show", :realistic_error_responses do
it "assigns service_request as @service_request" do
get :show, { company_id: @company.id, id: service_request.id }
expect(assigns(:service_request)).to eq service_request
end
it "returns 404 when service_request is not found" do
get :show, { company_id: @company.id, id: "foo" }
expect(response.status).to eq 404
end
end
Upvotes: 4
Reputation: 1089
A nicer way to write this is like so.
it "returns 404 when service_request is not found" do
get :show, { company_id: @company.id, id: "foo" }
expect(response).to have_http_status(:not_found)
end
And you can find other Rails HTTP Status symbols here.
Upvotes: -2
Reputation: 4517
Rails is throwing an ActiveRecord::RecordNotFound error instead of redirecting to a general 404 page. You need to handle that error with a rescue_from in the controller and redirect to a 404 view with status 404.
Upvotes: 3