srlrs20020
srlrs20020

Reputation: 437

Why can't the post method in my Rspec test find the create action/route for my PostsController?

Hi I have an Rspec test:

require "rails_helper"



describe PostsController do 


  let(:user){create(:user)}

  describe "POST #create" do 

    it "creates a Post" do 
      expect {post :create, post: attributes_for(:post)}.to change(Post, :count).by 1
    end


  end


end

That is throwing the following error:

ActionController::UrlGenerationError:
       No route matches {:action=>"create", :controller=>"posts", :post=>{:content=>"this is post content!"}}

Which means it can't find the route right?

instead of passing :create as the first argument to post I have tried, passing it the route helper user_posts_path(user) <--- (this is the route for my posts create action), but I get pretty much the same error. Here is that attempt:

    it "creates a Post" do 
      expect {post user_posts_path(user), post: attributes_for(:post)}.to change(Post, :count).by 1
    end

which throws this error:

ActionController::UrlGenerationError:
       No route matches {:action=>"/users/1/posts", :controller=>"posts", :post=>{:content=>"this is post content!"}}

I've also attempted to pass in the id manually:

id: user.id

as the second argument to post.

Here is the post_factory.rb since I am calling attributes_for(:post):

FactoryGirl.define do 

  factory :post do 
    content "this is post content!"
    user
  end
end

My relevant rake routes:

user_posts GET    /users/:user_id/posts(.:format)        posts#index
                 POST   /users/:user_id/posts(.:format)        posts#create
   new_user_post GET    /users/:user_id/posts/new(.:format)    posts#new
       edit_post GET    /posts/:id/edit(.:format)              posts#edit
            post GET    /posts/:id(.:format)                   posts#show
                 PATCH  /posts/:id(.:format)                   posts#update
                 PUT    /posts/:id(.:format)                   posts#update
                 DELETE /posts/:id(.:format)                   posts#destroy

My PostsController create action is alive and well too.

So I know my route is there and I have tried passing the post method an explicit route instead of :create, but I still get the same error. I believe the problem is occurring because my routes are nested, but I need them to be nested, and would like to test them in that form so I can't change the nesting. I'm not sure what else to do, so I've come here for help. Thanks.

Upvotes: 1

Views: 902

Answers (1)

Arun Kumar Mohan
Arun Kumar Mohan

Reputation: 11915

The posts#create action requires an user_id to be passed as a part of the url.

expect {post :create, post: attributes_for(:post)}.to change(Post, :count).by 1

should be

expect {post :create, user_id: user.id, post: attributes_for(:post)}.to change(Post, :count).by 1

user is available from the user factory which is lazily created(since you used let and not let!) when you call it inside the block.

Upvotes: 2

Related Questions