Best practices for testing Routes?

I’m wondering if there are any accepted practices for testing routes
in rails. For instance, if I added a route like:

map.root :controller => ‘welcome’

And I wanted to add an assertion like:

assert_routing ‘’, :controller => ‘welcome’, :action => ‘index’

Where should tests like this be placed? It seems like they could go
in a routes.rb testing class, but would that go in the functional
tests folder or in the integration folder? Or a test could be added
to the welcome controller’s tests, since it’s the one that should
handle the request.

I’ve been looking around online, and looking through some open source
rails apps, but I haven’t found an answer yet. Is there a right place
for this?

Why would you want to test that? There are already tests written for
that
(in the rails code itself), map.root :controller => “welcome” will
always go
to :controller => “welcome”, :action => “index”

On Dec 17, 2007 2:05 PM, ryan_s [email protected] wrote:

Where should tests like this be placed? It seems like they could go


Ryan B.

Maybe I’m being overly defensive in my testing.

I tend to take the perspective that there should be a test for
anything that I expect the application to do. That way the tests can
act as a specification for what is expected of the app, and also they
guard against me doing something stupid in the future, like adding a
higher priority route that preempts the route I’m testing.

As I said before there are already tests for this. You shouldn’t be
testing
the routing unless you’re changing the actual code of it.

Testing something like whether or not a page redirects somewhere is
recommended, but going as far as to test something that’s core Rails
stuff,
I wouldn’t bother testing it. It should always do what you think it
should
do, unless you’re not using a stable release.

I was trying to provide the simplest example possible to avoid forcing
people to read too much, but I’m afraid my example might have been too
simple. I don’t intend to test that “map.root” works, instead I want
to test that my application routes requests the way I want it to.

Here is a more in depth example of the sort of tests I’m thinking of.
Say I wanted to create a blog like the one described in example 2 of
the Rails Introduction to Routes page at
Peak Obsession.

If I approached this using test driven methodology I would write a
test and then add a route to fulfill that test. So, when I added my
posts/show/10 route there would have been a test proving that it
worked. Later when I added the new route from the example:

map.connect ‘:year/:month/:day’, :controller => ‘blog’, :action =>
‘by_date’

I would immediately notice that my posts/show/10 test failed. Then it
wouldn’t take long to realize that the new route was too vague, and it
was matching the posts route when it shouldn’t. So, I could get to
the better route from the example with less effort:

map.connect ‘date/:year/:month/:day’, :controller => ‘blog’, :action
=> ‘by_date’,
:month => nil, :day => nil,
:requirements => {:year => /\d{4}/, :day => /
\d{1,2}/, :month => /\d{1,2}/}

Without tests to validate my routes I might not have noticed this
mistake as quickly, and once I did notice it might take me longer to
find the problem if I had made other changes between adding the
problem route and noticing the problem.

I realize not everyone uses TDD, but I’m sure some Rails developers
do. I’m wondering if any test first Rails people out there have any
advice on where to stick tests of this nature.

On Dec 17, 2007, at 12:37 AM, ryan_s wrote:

If I approached this using test driven methodology I would write a
the better route from the example with less effort:
problem route and noticing the problem.

Testing something like whether or not a page redirects somewhere is
recommended, but going as far as to test something that’s core
Rails stuff,
I wouldn’t bother testing it. It should always do what you think it
should
do, unless you’re not using a stable release.

ryan_s,
I tend to put these tests in the same file that tests the controller
to which the route is connected. For the example in this message,
that’d be in test/functional/blog_controller_test.rb. But know that
there are two forms that your testing needs to take.

For a GET route, it’s as simple as (I always put a test that the
controller name is right, too):

def test__controller_naming
assert_equal(‘similarity’, @controller.controller_name,
“None of the routing tests will work if
controller_name is not ‘similarity’”)
end

for a non-standard default action

def test__route_similarity_categories
assert_routing ‘/similarity’, { :controller =>
‘similarity’, :action => ‘categories’ }
end

for a nested-ish resource

def test__route_similarity_candidates
assert_routing(‘/similarity/1/group/2’,
{ :controller => ‘similarity’, :action => ‘list’,
:id => ‘1’, :trait_group => ‘2’ })
end

However, if you want to test that the specific kind of request is
used, you need to use the two separate methods that assert_routing
uses internally because there’s no way to pass all the needed options
through.

Need to split these out in order to require that POST is used.

def test__route_similarity_make_similar
assert_recognizes({ :controller => ‘similarity’, :action =>
‘make_similar’,
:id => ‘1’, :trait_group => ‘2’, :leader =>
‘3’, :follower => ‘4’ },
{ :path => ‘/similarity/1/group/2/3/4’, :method
=> :post })

 assert_generates('/similarity/1/group/2/3/4',
                  { :controller => 'similarity', :action =>

‘make_similar’,
:id => ‘1’, :trait_group => ‘2’, :leader =>
‘3’, :follower => ‘4’ })
end

This route happens to be for an AJAX’d action so less fluff in the URL
wasn’t a concern.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On 12/17/07, ryan_s [email protected] wrote:

I was trying to provide the simplest example possible to avoid forcing
people to read too much, but I’m afraid my example might have been too
simple. I don’t intend to test that “map.root” works, instead I want
to test that my application routes requests the way I want it to.

The way I think about this is that I’m testing that what I put in my
config/routes.rb file does what I think it should.

For those using RSpec, the latest version makes two specs for a
controller if you use the “script/generate rspec_scaffold foo” command

specs
controllers
foos_controller_spec.rb
foos_routing_spec.rb

The foos_controller_spec.rb corresponds roughly to the test case for
the controller in the test/integration directory and contains
specifications of the behavior of the controller.

The foos_routing_spec.rb contains specs for routes pertaining to the
FoosController.

I was quite skeptical about Rspec when I first learned of it a year
ago, but it’s winning me over.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Thanks Rob, this is just the sort of information I was looking for.

Ryan

On Dec 17, 7:10 am, Rob B. [email protected]

That’s interesting Rick. I’ve been meaning to look into RSpec for a
while now, but this gave me the impetus to actually do it. It looks
to me like a nice way of providing more verbose tests. I think I’ll
give it a try and see how I like it. Thanks for the tip.

Ryan