eliotsykes/rspec-rails-examples

Have request specs handle errors like production

eliotsykes opened this issue ยท 8 comments

Currently request specs that cause HTTP errors like 404 via RecordNotFound will raise exceptions instead of responding with 404.

Do one of these:

  • without_error_debugging (previously with_rails_error_handling) in a spec/support/error_helper.rb that is included with request specs: rails/rails#11289 (comment)
    OR
  • Comment out action_dispatch.show_exceptions = false in config/environments/test.rb and set action_dispatch.show_detailed_exceptions = true

Prefer without_error_debugging option used as needed in specs. The 2nd option may suppress useful error information in other tests.

As an aside, this Rails change from 2010 is where the action_dispatch.show_exceptions = false was added to the test environment config. Its not yet clear what the reason was for choosing this as the default for all new Rails apps.

Issue: https://rails.lighthouseapp.com/projects/8994/tickets/4315-raise-exceptions-instead-of-rendering-exceptions-templates-in-test-environment
Commit: rails/rails@d898a4b

# spec/support/error_responses.rb
module ErrorResponses

  # See: https://github.com/rails/rails/pull/11289#issuecomment-118612393
  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
end

Usage:

    it "responds with 400 Bad Request HTTP status for no params" do

      no_parameters = {}.to_json

      respond_without_detailed_exceptions do
        post "/api/v1/sessions", no_parameters, json_request_headers
      end

      expect(response).to have_http_status(:bad_request)
      expect(response.content_type).to eq("application/json")

      expect(json).to eq(status: "400", error: "Bad Request")
    end

To configure within a spec to have all examples use production-like error handling:

  around :each do |example|
    respond_without_detailed_exceptions do
      example.run
    end
  end

WIP: incorporating the above into #96

Closed by #96

Very useful, thank you!

This is awesome. Thank you very much @eliotsykes ๐Ÿ‘