DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Grant has posted 2 posts at DZone. View Full User Profile

Helper For Testing Default Routes Generated By A Resource In Ruby On Rails

09.10.2007
| 7247 views |
  • submit to reddit
        These methods test that the routes for resources defined in routes.rb are working as expected. Call them from your functional (controller) tests.

Add the following 3 methods to test/test_helper.rb (updated for Rails 1.2.5 which no longer uses semicolons as a separator for the edit action):
# Test for routes generated by map.resource (singular).
def assert_routing_for_resource(controller, skip=[], nesting=[])
  routes = [
    ["new",'/new',{},:get], ["create",'',{},:post],
    ["show",'',{},:get], ["edit",'/edit',{},:get],
    ["update",'',{},:put], ["destroy",'',{},:delete]
    ]
  check_resource_routing(controller, routes, skip, nesting)
end
# Test for routes generated by map.resources (plural).
def assert_routing_for_resources(controller, skip=[], nesting=[])
  routes = [
    ["index",'',{},:get], ["new",'/new',{},:get], ["create",'',{},:post],
    ["show",'/1',{:id=>'1'},:get], ["edit",'/1/edit',{:id=>'1'},:get],
    ["update",'/1',{:id=>'1'},:put], ["destroy",'/1',{:id=>'1'},:delete]
    ]
  check_resource_routing(controller, routes, skip, nesting)
end

# Check that the expected paths will be generated by a resource, and that
# the expected params will be generated by paths defined by a resource.
# routes is array of [action, url string after controller, extra params].
def check_resource_routing(controller, routes, skip=[], nesting=[])
  # set a prefix for nested resources
  prefix = nesting.join('s/1/')
  unless prefix.blank?
    prefix += "s/1/"
  end
  # Add params for nested resources.
  # For each 'nest', include a ":nest_id=>'1'" param.
  params = {}
  nesting.each do |param|
    params["#{param}_id".to_sym] = '1'
  end
  # Test each of the standard resource routes.
  routes.each do |pair|
    unless skip.include? pair[0]
      assert_generates("/#{prefix}#{controller}#{pair[1]}",
        {:controller=>controller,
        :action=>pair[0]}.merge(pair[2]).merge(params), {}, {},
        "Failed generation of resource route for action #{pair[0]} /#{prefix}#{controller}#{pair[1]}")
      assert_recognizes(
        {:controller=>controller,
          :action=>pair[0]}.merge(pair[2]).merge(params),
        {:path=>"/#{prefix}#{controller}#{pair[1]}", :method=>pair[3]},
        {}, "Failed to recognize resource route for path #{pair[3]}:/#{prefix}#{controller}#{pair[1]}")
    end
  end
end
EXAMPLES

You can specify actions to 'skip' (if you have a special route for that action).
If using nested resources, set the nesting array (use singular strings).

So, if you have the following in routes.rb:
map.make_thing '/make', :controller=>'things', :action=>'new'
map.resources :nests do |nest|
  nest.resources :things
end
map.resource :foo
then you can use the following in things_controller_test.rb:
def test_resource_routing
  assert_routing_for_resources 'things', ['new'], ['nest']
  assert_routing_for_resource 'foo'
end
    

Comments

Snippets Manager replied on Wed, 2010/01/27 - 10:36pm

This is a good test for people who are using TestUnit directly. I wrote a plugin for Shoulda users that is very similar, with a few additions. It tests :collection and :member routes as well. Here's a link to the explanation: http://bit.ly/test_routes