2016-04-27 132 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

劳拉,你救了我的命! –