Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test controllers with nested routes using Rspec?

I have 2 controllers that I created using scaffold generator of rails. I wanted them to be nested in a folder called "demo" and so ran

rails g scaffold demo/flows
rails g scaffold demo/nodes

Then I decided to nest nodes inside flows, and changed my routes file like so:

namespace :demo do 
  resources :flows do
    resources :nodes
  end
end

But this change resulted on the rspec tests for nodes breaking with ActionController::Routing errors.

  15) Demo::NodesController DELETE destroy redirects to the demo_nodes list
     Failure/Error: delete :destroy, :id => "1"
     ActionController::RoutingError:
       No route matches {:id=>"1", :controller=>"demo/nodes", :action=>"destroy"}

The problem is rspec is looking at the wrong route. It's supposed to look for "demo/flows/1/nodes". It also needs a mock model for flow, but I am not sure how to provide that. Here is my sample code from generated rspec file:

  def mock_node(stubs={})
    @mock_node ||= mock_model(Demo::Node, stubs).as_null_object
  end

  describe "GET index" do
    it "assigns all demo_nodes as @demo_nodes" do
      Demo::Node.stub(:all) { [mock_node] }
      get :index
      assigns(:demo_nodes).should eq([mock_node])
    end
  end

Can someone help me understand how I need to provide the flow model?

like image 998
picardo Avatar asked Jul 16 '11 01:07

picardo


1 Answers

You have two different questions going on here, so you may want to split them up since your second question has nothing to do with the title of this post. I would recommend using FactoryGirl for creating mock models https://github.com/thoughtbot/factory_girl

Your route error is coming from the fact that your nested routes require id's after each one of them like this:

/demo/flows/:flow_id/nodes/:id

When you do the delete on the object, you need to pass in the flow ID or else it won't know what route you are talking about.

delete :destroy, :id => "1", :flow_id => "1"

In the future, the easiest way to check what it expects is to run rake routes and compare the output for that route with what you params you are passing in.

demo_flow_node  /demo/flows/:flow_id/nodes/:id(.:format)   {:action=>"destroy", :controller=>"demo/flows"}
like image 131
iwasrobbed Avatar answered Nov 15 '22 21:11

iwasrobbed