Testing Custom and Named Routes
Problem
You want to test whether your customized routing rules are directing incoming URLs to actions correctly, and that options passed to url_for are translated into the correct URLs. Basically, you want to test what you've defined in config/routes.rb, including custom rules and named routes.
Solution
Assume you have a blog application with the following custom routing:
config/routes.rb:
ActionController::Routing::Routes.draw do |map|
map.home '', :controller => 'blog', :action => 'index'
map.connect ':action/:controller/:id', :controller => 'blog',
:action => 'view'
end
The Blog controller defines view and index methods. The view method returns an instance variable containing a Post if an :id exists in the params hash; otherwise the request is redirected to the named route, home_url.
app/controllers/blog_controller.rb:
class BlogController < ApplicationController
def index
end
def view
if (params[:id])
@post = Post.find(params[:id])
else
redirect_to home_url
end
end end
To test the generation and interpretation of URLs and the named route defined in routes.rb, add the following test methods to blog_controller_test.rb:
test/functional/blog_controller_test.rb:
require File.dirname(__FILE__) + '/../test_helper'
require 'blog_controller'
class BlogController; def rescue_action(e) raise e end; end class BlogControllerTest < Test::Unit::TestCase
def setup
@controller = BlogController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_url_generation
options = {:controller => "blog", :action => "view", :id => "1"}
assert_generates "view/blog/1", options
end
def test_url_recognition
options = {:controller => "blog", :action => "view", :id => "2"}
assert_recognizes options, "view/blog/2"
end
def test_url_routing
options = {:controller => "blog", :action => "view", :id => "4"}
assert_routing "view/blog/4", options
end
def test_named_routes
get :view
assert_redirected_to home_url
assert_redirected_to :controller => 'blog'
end
end
Run these functional tests with:
$ rake test:functionals
Discussion
Being able to test customized routing rules that may contain complex pattern matching is easy with the routing-related assertions that Rails provides.
The test_url_generation test method uses assert_generates, which asserts that the options hash passed as the second argument can generate the path string in the first argument position. The next test, test_url_recognition, exercises the routing rules in the other direction with assert_recognizes, which asserts that the routing of the path in the second argument position was handled and correctly translated into an options hash matching the one passed in the first argument position.
assert_routing in test_url_routing test tests the recognition and generation of URLs in one call. Internally, assert_routing is just a wrapper around the assert_generates and assert_recognizes assertions.
Finally, the named route (map.home) is tested in the test_named_routes method by issuing a get request to the view action of the Blog Controller. Since no id is passed, request should be redirected to the named route. The call to assert_redirected_to confirms that this redirection happened as expected.
See Also
|