DEV Community

Masato Ohba
Masato Ohba

Posted on

Automate Routing Specs in Rails with RouteMechanic

I guess some of Rails developers write tests as follows to ensure their applications' routings work well. I was one of them.

With assertions provided by Rails:

assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })

With rspec-rails:

expect(:get => "/articles/2012/11/when-to-use-routing-specs").to route_to(
  :controller => "articles",
  :month => "2012-11",
  :slug => "when-to-use-routing-specs"
)
expect(:delete => "/accounts/37").not_to be_routable

However, it's a kind of boring (at least for me) to add new test cases every when adding a new route. That's enough to motivate me to build a new gem.

RouteMechanic

Here's a gem that saves our time.

https://github.com/ohbarye/route_mechanic

You no longer need to maintain Rails' routing tests manually. RouteMechanic automatically detects broken routes and missing action methods in controllers once you've finished installation.

All you have to do is:

  • Install the gem.
  • Write one test that maintains your routing automatically, forever.

RSpec

Just add a test file that has only one test case using have_valid_routes matcher.

RSpec.describe 'Rails.application', type: :routing do
  it "fails if application does not have valid routes" do
    expect(Rails.application).to have_valid_routes
  end
end

MiniTest

Just add a test file like below.

class RoutingTest < Minitest::Test
  include ::RouteMechanic::Testing::Methods

  def test_that_application_has_correct_routes
    assert_all_routes
  end
end

What if RouteMechanic detects broken routes?

It tells you broken routes as follows.

  0) Rail.application fails if application does not have valid routes
     Failure/Error: expect(Rails.application.routes).to have_valid_routes

       [Route Mechanic]
         No route matches to the controllers and action methods below
           UsersController#unknown
         No controller and action matches to the routes below
           GET    /users/:user_id/friends(.:format) users#friends
           GET    /users(.:format)                  users#index
           DELETE /users/:id(.:format)              users#destroy
     # ./spec/rspec/matchers_spec.rb:8:in `block (2 levels) in <top (required)>'

1 examples, 1 failure, 0 passed

RouteMechanic reports 2 types of broken routes.

  1. Missing routes
    • Your application has the controller and the action method but config/routes.rb doesn't have corresponding settings.
  2. Missing action methods
    • Your application's config/routes.rb has a routing declaration but no controller has a corresponding action method.

Is routing spec necessary?

Reasonable question. I believe most Rails developers write request specs instead of routing specs, and you might wonder what's worth to automate routing specs.

Having said that, I can come up with some situations that you might want to have routing specs.

  1. When your project is kinda aged and none knows which route is alive and which one is dead.
    • You can detect dead code by using this gem.
  2. When your application doesn't have enough request specs (even controller specs).
    • This gem could be a good start point to increase tests to ensure routing is valid.
  3. When you try to make a big refactor of config/routes.rb.
    • It's a burden to run all request specs during refactoring. This could save your time.
  4. When you're compelled to write routing specs by any pressure. ;-)
    • Set you free from tedious work!

Feedbacks or bug reports are welcome!

https://github.com/ohbarye/route_mechanic

Discussion (0)