Where to test routes in ruby on rails
Why do you feel the need to test the routes? Purely to make sure that the routes defined in your routes.rb actually work? If so, then don't. That's not the job of your application's tests to make sure that the framework's internals operate properly - that's the job of the Rails framework's own tests.
If perhaps you have some sort of dynamic/user definable route that you want to test, I'd probably go with integration.
Routes should be done as part of integration tests. Integration tests are where you test the important work flows of your application - more specifically whether a URL is defined or not seems to be an important workflow.
Your integration test would look like any normal integration test:
# /tests/integration/routes_test.rb
require 'test_helper'
class RoutesTest < ActionController::IntegrationTest
test "route test" do
assert_generates "/photos/1", { :controller => "photos", :action => "show", :id => "1" }
assert_generates "/about", :controller => "pages", :action => "about"
end
end
As to @jemminger's response of not testing routes - While it is Rail's tests that verify that routes.rb works, it's not Rail's responsibility to test whether http://yoursite.com/users
is defined in your routes. The caveat is that most route testing could be done in existing integration tests, so specific tests for routes could be redundant.
The specific use case I can think of are all the people that have already, or are going to upgrade from Rails 2 to Rails 3. The code to define routes has changed significantly, and it's better to find out from tests that the routes were upgraded correctly, than from users when they report 404 errors.
According to a comment in this rails bug, the proper place is in a functional test. If you try to test them in an integration test, the routes you established in routes.rb
will not be available.
require 'test_helper'
class FooControllerTest < ActionController::TestCase
test "foo routes" do
assert_recognizes({:controller => 'foo_controller', :action => 'list'}, '/foos'
end
end
Route tests are good places to list links that exist in the wild, and avoid inadvertently breaking them with a code change. It's a little strange that the tests are scoped to a controller, since it's the route set as a whole you're actually testing, but I haven't heard of a 'route set test'.
I suggest you create a test file for the routes in your test/controllers folder.
class HomeRoutesTest < ActionController::TestCase
test "must route to home index" do
assert_routing '/', controller: "home", action: "index"
end
end
It was mentioned that they belong to integration test. I disagree. You merely test routes, that's it. So it would rather fall into functional or even unit testing instead of integration testing.
You can find a reference in the Rails RailsGuide Testing, section 9. Testing Routes
Integration tests are for the flow, where you test the interaction of different controller action, e.g. executing a business process like user logs in, browses the site and puts an item into the basket. That said your integration tests won't work if your routes don't work. Thus many say that integration tests is the place where you test routes. However, considering the development cycle, you would create unit tests, controller tests, route tests, etc. first before doing the integration tests.
And on another note: assert_routing
does both tests: assert_generates
and assert_recognizes
.