I’ve not found any blog post or article about how to easily test CORS support implemented in a Rack middleware (e.g. using the rack-cors gem) with RSpec in Rails. So, after figured out I decided to write some small tips I learned from it.
I assume you have a fairly updated Rails app, I tested it with Rails 4.2.x, with RSpec tests support, and you want to add support for CORS headers.
Install rack-cors gem
it’s better to follow the gem instructions (you’ll find the most updated instructions there) than a blog post, but anyway here’s how I did it:
Add this to your Gemfile:
1
| |
Add this to your config/application.rb:
1 2 3 4 5 6 | |
These are the common options, tune it to your needs. Here we’re allowing requests from any domain for the get, post, patch and options methods. options is a special method used for preflight requests.
That’s it. CORS is now active in this Rails app. Every time we send a request with the CORS headers, we’ll receive the CORS response headers.
How to test it with cURL
With cURL, it’s easy to test CORS. Let’s see the most common scenarios:
Sending the Origin header:
-H: Header to include in the request.-I: Fetch theHTTPheader only.
1
| |
We should receive: Access-Control-Allow-Origin: *.
Sending the preflight options method:
Send a options request with Origin: *, Access-Control-Request-Method: get and Access-Control-Request-Headers: test.
* -X: Specifies a custom request method
1
| |
We should receive Access-Control-Allow-Origin: *, Access-Control-Allow-Methods: get, post, patch, options, and Access-Control-Allow-Headers: test.
How to test it with RSpec
Support CORS is a bit tricky to test with RSpec, because we don’t have a real server (like Webrick, Unicorn or Puma) between the code and the client. This usually is not a problem but it does affect in this particular case, and the rfc3875 explains why. The server translate the custom HTTP request headers in this way:
- Convert to upper case.
- Replace
-with_ - Prepend
HTTP_.
Because we don’t have the server to do it for us, we must do it manually. For example, the Origin becomes HTTP_ORIGIN and Http-Access-Control-Request-Method becomes HTTP_ACCESS_CONTROL_REQUEST_METHOD.
Let’s see some example tests:
Sending the Origin header:
1 2 3 4 5 6 7 | |
Sending the preflight options method:
1 2 3 4 5 6 7 8 9 10 | |
Note: You must use integration tests to be able the test through rack. A controller test doesn’t trigger rack, it’s like an unit test for the controller.
Don’t forget to uppercase, replace - and prepend HTTP_ to all your custom HTTP headers when testing!



