Where to test routes in ruby on rails
Solution 1
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.
Solution 2
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.
Solution 3
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
.
Solution 4
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'.
Anthony Serdyukov
I'm a CTO at EDISON Software Development company with 10 years of experience. I'm specialized in .NET, Qt, web Development, cryptography, federated authentication, project management, architecture and system design.
Updated on June 14, 2022Comments
-
Anthony Serdyukov about 2 years
Where to test routes in ruby on rails?
- unit tests?
- functional tests?
- integration tests?
Addition:
To be exact, where to apply assertions described on guides and on api?
-
Anthony Serdyukov over 13 yearsPlease take a look at addition to the question.
-
jemminger over 13 yearsAgain, ask yourself "Why?" You should be testing the parts of your application that are outside the scope of the basic framework's responsibilities, and that are potential failure points. If you have some routes that need testing under different scenarios, then use those route testing helpers. I would probably use them in functional and/or integration tests.
-
Anthony Serdyukov over 13 years"Why?" is another question. It's reasonable, but another. There are dedicated assertions and the question is where to use them?
-
jemminger over 13 yearsRoutes deal with URLs, so my inclination would be to test them in functional/integration tests. They might not even be included by default in unit tests. Ultimately, there's no hard rule where it's permissable or forbidden.
-
Michael Durrant almost 13 yearsI think that the important thing that gets tested here (as it should be) is that the route exists at all. So the application structure is getting tested. That way if someone changed a route that a function depends on then there is a test to catch that. i.e. you don't need to test so much that the route 'works' just that it 'exists'. You'll test separately whether it 'works' with controller testing. So as always tests are never required... but strongly recommended and the more of your application that you depend on, the more comprehensive your tests should be.
-
mrt almost 10 yearsJust a note that the
assert_recognizes
might be the assertion you wanna use. -
Debajit almost 10 yearsRedirected routes (which do not have a controller e.g. if you redirect say an old RSS feed to a new RSS feed url) cannot be tested in functional tests. They can only be part of an integration test (At least if you're using Minitest)
-
Ely about 9 yearsThis answer should not be the accepted answer. Routes testing should belong to Functional Tests, as referenced in the RailsGuides for Testing.
-
Marius Butuc about 9 yearsFor newer versions of Rails, your class should inherit from
ActionDispatch::IntegrationTest
as opposed toActionController::IntegrationTest
-
Daniel about 8 yearsExample code here on rail guides: guides.rubyonrails.org/testing.html#testing-routes
-
Michael Wang over 6 yearsThe purpose of testing routes is not to test Rails internal operation. It's to test if I wrote the routes.rb correctly. E.g. it's common to missing 's' in "get '/users', to: 'user#index'", you want to catch this kind of error in build time instead of runtime.
-
jemminger over 6 years@MichaelWang Wouldn't your controller or integration tests catch those?
-
Michael Wang over 6 years@jemminger Yes, if the routes is defined by standard resources, I would test them in controller tests. But there are cases for customized routes, such as "get '/colleagues', to: 'user#index'". In such cases, I don't think it's controller tests' responsibility to test them. Therefore, as you suggest, a good place to test would be integration test.