route it, route it, route it out loud

Do you have to test your routes?

Yes.

There’s no reason you shouldn’t be automating the testing of your routes. The alternative would be to open up a browser and type in each pretty url, that’s no good. How do you test them?

There’s basically 2 ways I’ve tested routes.

1.) Create a separate test file just for routes:

test/functional/routestest.rb


require File.dirname(FILE) + '/../testhelper'

class RoutesTest < Test::Unit::TestCase

def testshouldrouteausertotheblogscontroller assertrouting 'blogs', :controller => 'blogs' :action => 'index' assertrouting 'blogs/1', :controller => 'blogs', :action => 'show', :id => '1' end

end

Here all your routes test are in one place. But you have to scan this test file to find a test for a route for a specific action, this could take time.

2.) Put the assertions in the functional test for the action the route maps to:

test/functional/locationscontrollertest.rb


  def testshouldfindthelocationrecordwiththegivenidonGETto_edit
    get :edit, :id => locations(:boloco).id

assert_equal locations(:boloco), assigns(:location)
assert_response :success
assert_template 'edit'

assert_recognizes({ :controller => 'admin/locations',
                    :action => 'edit',
                    :id => '1' },
                  :path => 'admin/locations/1;edit', 
                  :method => :get)

end

This is nice because the route test is right along side its action’s test.

What’s assertions should I be using?

There’s 3 assertions you can use:

1.) #assert_generates - tests that something like:


'blogs'

generates:


{ :controller => 'blogs', 
  :action => 'index' }

ex)


  assert_generates 'blogs',
                   :controller => 'blogs',
                   :action => 'index'

2.) #assert_recognizes - tests that something like:


{ :controller => 'blogs', 
  :action => 'index' }

generates:


'blogs'

ex)


 assert_recognizes({ :controller => 'blogs',
                     :action => 'index' },
                     :path => 'blogs', 
                     :method => :get)

That


:method => :get

in there is specifying the HTTP verb, a GET request.

3.) #assertrouting - test that #assertgenerates and #assert_recognizes pass

Will test that both:


'blogs'

generates:


{ :controller => 'blogs', 
  :action => 'index' }

and


{ :controller => 'blogs', 
  :action => 'index' }

generates:


'blogs'

ex.)


  assert_routing 'blogs', :controller => 'blogs',
                          :action => 'index'

Use #assertrouting if you’re not using RESTful routes. If you’re using RESTful routes you’ll want to specify the HTTP verb in route assertions and only #assertrecognizes supports this, so that’s your only move.

Jared Carroll