huesler.io My 2 cents

Rails - Testing rescue action in public behavior

Rails handles exceptions that occur in production mode by rendering the file public/500.html or one of the other two (404.html and 422.html) if appropriate. Generally this is a good default, but in some cases it is a requirement to redirect the user to, or render specific pages for different types of exceptions. For instance, when an application provides a JSON API, it would be bad to return a 500.html to the caller when something goes wrong.

There are generally two ways do this in Rails. Either overwrite rescue_action_in_public in your controller or use the newer rescue_from to map exceptions to a handler. Ryan Daigle wrote a short but comprehensive blog post on this topic.

However, testing this is a bit tricky. config.consider_all_requests_local needs to be set to false and local_request? should be set to false as well. Testing this manually in the browser is cumbersome and error prone, so I needed a way to verify the behavior with a controller test. A quick ack --ruby rescue_action_in_public actionpack-2.3.4 turned up /actionpack-2.3.4/test/controller/rescue_test.rb exactly what I needed.

As it turns out, this is actually quiet easy to test. Basically, there are four things to consider and you are good to go:

1. Simulate the production environment in a setup method

2. Create a dummy controller with actions that reproduce the errors you want to test

3. Generate a route for your dummy controller if you have deleted the default routes in routes.rb

4. Call those methods in your test cases

With these four steps we got most uses cases covered. I ran into a problem, where I wanted to test an error that occurred during template rendering and required some special exception handling code. This is what worked for me: