What to test in Rails routing?
Asked Answered
A

2

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?

Archaeopteryx answered 7/8, 2013 at 19:46 Comment(3)
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?Jersey
You should also assert that true == true...Uriel
@Archaeopteryx FYI: I had to find a solution for testing unassigned routes, too.Fewness
T
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.

Tibetan answered 8/8, 2013 at 3:56 Comment(3)
Can you explain the second point, when you must reject some routes? Do you mean that you're explicitly testing that a certain route does not exist?Archaeopteryx
What is a public facing API?Adelleadelpho
@JohnCalebOsborne An API for public consumption. As opposed to an internal API, for which explicit tests aren't as necessary-they'd be tested via whatever uses them.Tibetan
R
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
Repp answered 8/8, 2013 at 3:17 Comment(2)
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.Archaeopteryx
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.Repp

© 2022 - 2024 — McMap. All rights reserved.