user160917
user160917

Reputation: 9350

Testing nested controller action with RSpec

I have routes set up that look like:

match '/things/:thing_id' => "descriptions#index", :as => :thing
resources :things, :except => [:show] do 
  ...
  resources :descriptions, :only => [:create, :index]
end

How would I test the :create method for the nested descriptions?

So far i've got

context "with user signed in" do

  before(:each) do
    user = Factory.create(:user, :name => "Bob")
    controller.stub!(:authenticate_user!).and_return(true)
    controller.stub!(:current_user).and_return(user)
  end

  describe "PUT create" do

    before(:each) do
      @thing = Factory.create(:thing)
      params = {"text" => "Happy Text"}

      post thing_descriptions_path(@thing.id), params  #Doesn't work
      post :create, params                             #Doesn't work

    end
  end
end

Upvotes: 2

Views: 2050

Answers (1)

nmott
nmott

Reputation: 9604

The following should work:

describe "PUT create" do

  before(:each) do
    @thing = Factory(:thing)
    attrs = FactoryGirl.attributes_for(:description, :thing_id => @thing)

    post :create, :thing_id => @thing, :description => attrs
  end
end

To create a nested resource you need to tell rspec the parent id in the post create so that it can insert it into the route.

You also need to create your :descriptions factory with the relationship to :thing built in, and also pass the thing_id into the :description attribute creation, this is to make sure that Factory Girl doesn't go and create a new :thing when it creates the attributes for :description, while this wouldn't cause the test to fail it would slow it down as you would end up creating two instances of :thing.

Upvotes: 3

Related Questions