2016-04-27 125 views
0

我的規格一般工作正常,但是當我嘗試測試嵌套的控制器時,出現奇怪的錯誤。所以這個代碼模式subject(:create_action) { xhr :post, :create, post_id: post.id, post_comment: attributes_for(:post_comment, post_id: post.id, user: @user) }我控制器無法嵌套工作正常,但在這裏我命名空間控制器測試it "saves the new task in the db引發以下錯誤:rspec中的rails命名空間控制器測試

1) Posts::PostCommentRepliesController when user is logged in POST create with valid attributes saves the new task in the db 
    Failure/Error: subject(:create_action) { xhr :post, :create, post_comment_id: post_comment.id, post: attributes_for(:post_comment_reply, post_comment: post_comment, user: @user) } 

    ArgumentError: 
     wrong number of arguments (4 for 0) 

我應該怎麼做才能使這項工作?如您所見,我將post_comments_controller_spec.rb放在specs/controllers/posts文件夾中,並要求posts/post_comments_controller,但它無濟於事。

的routes.rb

resources :posts do 
    resources :post_comments, only: [:create, :update, :destroy, :show], module: :posts 
end 

規格/控制器/職位/ post_comments_controller_spec.rb

require "rails_helper" 
require "posts/post_comments_controller" 

describe Posts::PostCommentsController do 

    describe "when user is logged in" do 

    before(:each) do 
     login_user 
    end 

    it "should have a current_user" do 
     expect(subject.current_user).to_not eq(nil) 
    end 

    describe "POST create" do 
     let!(:profile) { create(:profile, user: @user) } 
     let!(:post) { create(:post, user: @user) } 

     context "with valid attributes" do 
     subject(:create_action) { xhr :post, :create, post_id: post.id, post_comment: attributes_for(:post_comment, post_id: post.id, user: @user) } 

     it "saves the new task in the db" do 
      expect{ create_action }.to change{ PostComment.count }.by(1) 
     end 
     end 
    end 
    end 
end 

回答

2

這是一個稍顯怪異的bug。簡而言之,您的let!(:post) { ... }最終在用於發佈發佈請求的示例組上覆蓋了一個名爲post的方法。

發生這種情況的原因是,您在given example group中定義了一個describe,同名的RSpec defines you a method內的let

describe Post do 
    let(:post) { Post.new } 

    it "does something" do 
    post.do_something 
    end 
end 

xhr method(連同getpost等),在另一方面,是從導軌本身測試一個輔助方法。 RSpec includes this module與助手,以便它在測試中可用。

describe PostController, type: :controller do 
    let(:comment) { Comment.new } 

    it "can post a comment thanks to Rails TestCase::Behaviour" do 
    post :create, comment 
    # xhr :post, ... under the covers calls for post method 
    end 
end 

因此,例如組對象有一個方法稱爲後,當您創建的讓利投入,RSpec的去創造你相同名稱的方法組對象上,從而覆蓋原來的(和急需的) post方法。

describe PostController, type: :controller do 
    let(:post) { Post.new } 

    it "mixes up posts" do 
    post :create, post # post now refers to the variable, so this will cause an error 
    end 
end 

輕鬆解決這個問題,我會建議命名let(:post)別的東西,像new_post例如。

describe PostController, type: :controller do 
    let(:new_post) { Post.new } 

    it "does not mix up posts" do 
    post :create, new_post # no more conflict 
    end 
end 
+0

勞拉,你救了我的命! –