为什么我的Rspec测试中的post方法找不到我的PostsController的创建动作/路由?

时间:2016-09-07 13:58:39

标签: ruby-on-rails rspec

您好我有一个Rspec测试:

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

这会引发以下错误:

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

这意味着它无法找到合适的路线?

而不是传递:创建作为发布的第一个参数我已经尝试过,传递路由帮助器user_posts_path(用户)< ---(这是我的帖子创建动作的路径),但我得到的几乎是同样的错误。这是尝试:

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

会抛出此错误:

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

我还试图手动传入id:

id: user.id

作为发布的第二个论点。

这是post_factory.rb,因为我正在调用attributes_for(:post):

FactoryGirl.define do 

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

我的相关佣金路线:

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

我的PostsController创建动作也很有效。

所以我知道我的路线在那里,我尝试将post方法传递给显式路径而不是:create,但我仍然得到相同的错误。我相信问题正在发生,因为我的路由是嵌套的,但我需要它们嵌套,并且希望以该形式测试它们,这样我就无法更改嵌套。我不确定还能做什么,所以我来这里寻求帮助。感谢。

1 个答案:

答案 0 :(得分:0)

posts#create操作要求user_id作为网址的一部分传递。

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

应该是

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

user可以从user工厂获得,当您在块中调用它时,它会被懒惰地创建(因为您使用了let而不是let!)。