---
title: route it, route it, route it out loud
teaser: How to test routes in Rails applications.
tags: web,rails
author: Jared Carroll
published_on: 2007-06-27
---

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:

In `test/functional/routes_test.rb`:

```ruby
require File.dirname(__FILE__) + '/../test_helper'

class RoutesTest < Test::Unit::TestCase

  def test_should_route_a_user_to_the_blogs_controller
    assert_routing 'blogs', :controller => 'blogs'
                            :action => 'index'
    assert_routing '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:

In `test/functional/locations_controller_test.rb`:

```ruby
def test_should_find_the_location_record_with_the_given_id_on_GET_to_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:

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

ex)

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

2.) #assert\_recognizes - tests that something like:

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

generates:

    'blogs'

ex)

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

That

```ruby
:method => :get
```

in there is specifying the <abbr title="HyperText Transfer Protocol">HTTP</abbr>
verb, a GET request.

3.) #assert\_routing - test that `#assert_generates` and `#assert_recognizes`
pass

Will test that both:

    'blogs'

generates:

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

and

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

generates:

    'blogs'

ex.)

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

Use `#assert_routing` if you're not using RESTful routes.  If you're using
RESTful routes you'll want to specify the <abbr title="HyperText Transfer
Protocol">HTTP</abbr> verb in route assertions and only `#assert_recognizes`
supports this, so that's your only move.
