How to test routes in a Rails 3.1 mountable engine

This problem has been eluding me for a few weeks...

While working on Blogit I wanted to write specs for the routes but kept hitting ActionController::RoutingError with every approach I tried.

Finally I discovered this solution:

# spec/routing/post_routing_spec.rb

...

before do
  @routes = Blogit::Engine.routes
end

it "routes /posts/page/:page to posts#index with page param" do
  { get: "posts/page/2" }.should route_to({
    controller: "blogit/posts",
    action: "index",
    page: "2"
  }
end

Setting the @routes variable to the Blogit Engine's routes seemed to do the trick nicely!

There's something really dirty and "hacky" about this approach though - there surely is a better way? If anyone knows, please leave a comment below.

Comments

This is for MiniTest controller specs? I've been having this exact problem. Will dig further & shout if I discover anything. Thanks for the lead.


Nice blog! Faild to subscribe through google reader, there is no rss feed!

Posted on by Meta

@Seth Bro - I was using plain old RSpec but it seems to be a problem with all testing suites.

If you do find a solution I'd be grateful if you share :)


@Gavin Morrice

With Rails 3.1, I was using this hack (http://www.builtfromsource.com/2011/09/21/testing-routes-with-rails-3-1-engines/#comment-4357) to load routes dynamically. In my opinion, this is a cleaner solution because it does not involve having before { @routes = Blogit::Engine.routes } in all routing specs. You just need to add a "config.include Blogit::Engine.load_routes" somewhere in your spec_helper.rb (or in your spec/support folder). ;-)

But Rails 3.2 came out and this code became deprecated. So, I made some investigation to find what has changed and to solve this issue... If you're interested, my change can be found here: https://github.com/asellus/persona/commit/e0a73cc61942345b24f6186b5928c922072a7a44

Hope it helps! :-)

Posted on by Xavier Dutreilh

Interesting solution Xavier - thanks :)


Why not leave me a comment?


(never displayed)