9

I'm curious what people consider adequate/thorough testing of routes. A guy I work with seems to want to assert every route in our routes file, no matter how standard. I feel like this is a waste of time, but maybe I'm wrong and there is some value to this I'm unaware of.

There are a few cases where I can see some value in routing. We still have a couple actions that respond to both GET and POST requests, although I've been meaning to get rid of those. We don't have any kind of crazy constraints with lambdas or anything, but that seems like it would be worth testing if we did.

But for a normal resources definition?

resources :foo, only: [:index, :show]

We have assertions that both of these routes exist, we assert that they're GET and that they go to the correct controller/action. Is there any point to any of that? It feels like we're just testing Rails at this point.

On a slightly related question, I prefer to have resource routes defined like the one above (with the only: [:index, :show] part). Are there any consequence to only defining resources :foo in the routes file if there are only index/show actions on that controller?

It seems to me that it's probably just using more time and/or memory, but is it somehow also a security concern or something really bad that I'm unaware of?

James Chevalier
  • 10,604
  • 5
  • 48
  • 74
bratsche
  • 2,666
  • 20
  • 23
  • 1
    One way of looking at it is that you're testing for /foo/index and /foo/:id so that you avoid accidentally screwing up the routes file without realizing it... Who *hasn't* accidentally the whole thing? – James Chevalier Aug 07 '13 at 20:33
  • You should also assert that true == true... – Stephan1990 Aug 07 '13 at 20:57
  • @bratsche FYI: I had to find a solution for [testing unassigned routes](http://stackoverflow.com/questions/18357389/how-to-test-a-controller-action-that-does-not-exist), too. – JJD Aug 21 '13 at 14:51

2 Answers2

5

The biggest reasons to test routes isn't to double-test Rails, but rather to verify a public-facing API.

This reduces regressions against advertised entry points irrespective of the data they take or return.

What level to test these at is open to some debate as well; is it valuable to test the route itself, or does it only make sense to also verify data going in/coming out? Doing so also tests the same routes, and I'd argue is more valuable–but slower.

I tend to only test routes directly when:

  • They're a little funky, e.g., not bog-standard routes
  • I must reject some routes
  • During preliminary development.

Preliminary route tests generally get deleted once they're tested in other ways.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
4

I test routes to ensure that routes I want permitted are open but also so that routes I want shut down do not work. I split the routing spec into three contexts - permitted routes, not permitted routes and custom routes.

e.g. using rspec

describe SessionsController do
  describe "routing" do
    context "permitted" do
      it "routes to #create" do

        expect(post "sessions").to route_to("sessions#create")

      end
      ...
    end
    context "custom routes" do
      it "routes 'login' to #new" do

        expect(get "/login").to route_to("sessions#new")

      end
      ...
    end
    context "invalid routes" do
      it "does not route to #edit" do

        expect(get "/sessions/edit").not_to be_routable

      end
      ...
    end
  end
end
Richard Jordan
  • 8,066
  • 3
  • 39
  • 45
  • 1
    Can you explain the purpose of the third "invalid routes" context? This was kind of the second part of my question, which is somewhat related. But if you have "resources :sessions" (and you don't include an 'only' clause), and you also do not have a SessionsController#edit method.. what happens? I never do this, but I'm just curious if there are any huge (like security) problems that arise. – bratsche Aug 08 '13 at 04:10
  • 2
    The purpose, for me anyway, is to ensure I haven't left any routes open that I didn't plan for. I think it's best to avoid exposing any paths through the application I haven't explicitly opened. When I'm doing TDD I only include routes (using :only) that I am writing code behind. I therefore want any other routes to be blocked and I want my tests to tell me this is the case. It also means I cannot accidentally make changes to the routes file without breaking tests. A better example would be users#index should not route, where I don't want it exposed. – Richard Jordan Aug 08 '13 at 04:56