How to Check Routes in a Rails 3.1 Mount Engine

I am trying to write some routing specifications for a mounted rail 3.1. I have a working model and controller specifications, but I cannot figure out how to specify the routes.

For the model with the "testy" sample, each of my approaches ends with the same error:

ActionController::RoutingError: No route matches "/testy" 

I tried the syntax of Rspec and Test :: Unit (spec / routing / index_routing_spec.rb):

 describe "test controller routing" do it "Routs the root to the test controller index action" do { :get => '/testy/' }.should route_to(:controller => 'test', :action => 'index') end it "tries the same thing using Test::Unit syntax" do assert_routing({:method => :get, :path => '/testy/', :use_route => :testy}, {:controller => 'test', :action => 'index'}) end end 

I painted routes correctly (config / routes.rb):

 Testy::Engine.routes.draw do root :to => 'test#index' end 

And installed them in a dummy application (spec / dummy / config / routes.rb):

 Rails.application.routes.draw do mount Testy::Engine => "/testy" end 

And the rails server works and asks for http://localhost:3000/testy/ works fine.

Am I missing something obvious, or is it just improperly baked into the frame?

Update: As @andrerobot notes, rspec people fixed this issue in version 2.14, so I changed the accepted answer accordingly.

+18
ruby-on-rails ruby-on-rails-3 rspec2
Oct 07 2018-11-18T00:
source share
6 answers

Since RSpec 2.14 you can use the following:

 describe "test controller routing" do routes { Testy::Engine.routes } # ... end 

Source: https://github.com/rspec/rspec-rails/pull/668

+10
Jul 04 '13 at 19:06 on
source share

The answer from Stephen Anderson delivered me most of the way, but I need to make requests regarding the engine, not the application - probably because this technique replaces application routes with engine routes, so everything is relative to the engine now. It seems a little fragile to me, but I have not seen another way that works. If someone comes up with a cleaner way to do this, I will be happy to accept this answer.

In the application 'dummy', if the engine is installed as follows (spec / dummy / config / routes.rb):

 Rails.application.routes.draw do mount Testy::Engine => "/testy" end 

The following specification will correctly check the engine root route using the syntax rspec and test :: unit (spec / routing / index_route_spec.rb):

 require 'spec_helper' describe "test controller routing" do before(:each) { @routes = Testy::Engine.routes } it "Routes the root to the test controller index action" do { :get => '/' }.should route_to(:controller => 'testy/test', :action => 'index') end it "tries the same thing using Test::Unit syntax" do assert_routing({:method => :get, :path => '/'}, {:controller => 'testy/test', :action => 'index'}) end end 
+11
Nov 15 '11 at 17:36
source share

Try adding the block to the following:

 before(:each) { @routes = Testy::Engine.routes } 

This worked for me, as the routing specifications use this top-level instance variable to validate their routes.

+10
Nov 01 '11 at 13:52
source share

This worked for me:

 # spec_helper.rb RSpec.configure do |config| config.include MyEngine::Engine.routes.url_helpers end 
+4
Nov 10 2018-11-11T00:
source share

For me, it was a combination of comments from almost all the participants involved so far.

First, I started with this simple test:

  it "routes / to the widgets controller" do get('/').should route_to("mozoo/widget#index") end 

The result is:

 Failures: 1) Mozoo::WidgetController GET widget index routes / to the widgets controller Failure/Error: get('/').should route_to("mozoo/widget#index") ActionController::RoutingError: No route matches {:controller=>"mozoo/widget", :action=>"/"} # ./spec/controllers/mozoo/widget_controller_spec.rb:9:in `block (3 levels) in <module:Mozoo>' 

So, I switched from get('/') to { :get => '/' } , and everything started to work fine. I do not know why. According to lib / rspec / rails / matchers / routing_matchers.rb L102-105 , there is no difference, but it matters to me. Regardless, thanks @ cameron-pope.

Then I added another fairly simple and very similar test, as shown above:

 it "routes root_path to the widgets controller" do { :get => root_path }.should route_to("mozoo/widget#index") end 

And got this error:

 Failures: 1) Mozoo::WidgetController GET widget index routes root_path to the widgets controller Failure/Error: { :get => '/mozoo' }.should route_to("mozoo/widget#index") No route matches "/mozoo" # ./spec/controllers/mozoo/widget_controller_spec.rb:14:in `block (3 levels) in <module:Mozoo>' 

So, I added this:

 before(:each) { @routes = Mozoo::Engine.routes } 

And got a better / different error:

 Failures: 1) Mozoo::WidgetController GET widget index routes root_path to the widgets controller Failure/Error: { :get => root_path }.should route_to("mozoo/widget#index") The recognized options <{"controller"=>"mozoo/widget", "action"=>"index", "section"=>"mozoo"}> did not match <{"controller"=>"mozoo/widget", "action"=>"index"}>, difference: <{"section"=>"mozoo"}>. <{"controller"=>"mozoo/widget", "action"=>"index"}> expected but was <{"controller"=>"mozoo/widget", "action"=>"index", "section"=>"mozoo"}>. # ./spec/controllers/mozoo/widget_controller_spec.rb:14:in `block (3 levels) in <module:Mozoo>' 

From there, I modified my test to include a section (the namespace in which my engine is located):

 { :get => root_path }.should route_to(:controller => "mozoo/widget", :action => "index", :section => "mozoo") 

And viola, he passed. Thanks @ steven-anderson.

This next part is odd. After adding another test for a specific widget that used the widget_path URL helper for the named route:

  it "will successfully serve the widget show page" do visit widget_path(:foobar) response.should be_success end 

The test quickly inflates me:

 Failures: 1) GET bubble_summary_row widget will have the content section properly scoped Failure/Error: visit widget_path(:bubble_summary_row) NoMethodError: undefined method `widget_path' for #<RSpec::Core::ExampleGroup::Nested_3:0x0000010748f618> # ./spec/views/mozoo/widgets/show.html.haml_spec.rb:7:in `block (2 levels) in <module:Mozoo>' 

So, I added the following spec_helper configuration entry:

 RSpec.configure do |config| config.include Testy::Engine.routes.url_helpers end 

And BAM! It has passed. Thanks @ sam-soffes. What makes this weird is that later on when I created this comment, I deleted this configuration entry in order to try to return it, and I could not reproduce the error by simply deleting the config entry. Alright, I'm moving on. Hope this long count helps someone.

+1
May 30 '12 at 19:42
source share

Based on this answer, I chose the following solution:

 #spec/spec_helper.rb RSpec.configure do |config| # other code config.before(:each) { @routes = MyEngine::Engine.routes } end 

Added benefit is that you do not need to have a before(:each) block in each controller specification.

0
Mar 13 '13 at 7:40
source share



All Articles