Rspec ArgumentError: wrong number of arguments (given 2, expected 0)

Rspec ArgumentError: wrong number of arguments (given 2, expected 0)

我对嵌套对象(评论)进行了 rspec 测试,它嵌套在帖子对象中。这是 routes.rb:

  use_doorkeeper

  resources :posts do
    resources :comments 
  end

  root "posts#index"
end

这是评论控制器的一部分:

 class CommentsController < ApplicationController
  before_action :find_comment, only: [:destroy]
  before_action :authenticate_user!, only: [:destroy]

  def create
    @post = Post.find(params['post_id'])
    @comment = @post.comments.create(params[:comment].permit(:name, :comment, :user_id, :best, :file))
    respond_to do |format|
      format.html { redirect_to post_path(@post) }
      format.js
    end
  end
  private

  def find_comment
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
  end
end

这里是 rspec 测试:

 require 'rails_helper'

    RSpec.describe CommentsController, type: :controller do
      let(:user) { create(:user) }
      let(:post) { create(:post) }
    
      sign_in_user
    
      setup do
        allow(controller).to receive(:current_user).and_return(user)
      end
    
      describe 'POST #create' do
        context 'with valid attributes' do
          let!(:posts) { post :create, params: { post_id: post, comment: attributes_for(:comment) } }
    
          it 'saves the new comment in the database' do
            expect {{ comment: attributes_for(:comment) } }.to change(Comment, :count).by(1)
          end
        end
      end
    
    end

附加工厂文件以供评论:

 FactoryBot.define do
  factory :comment do
    comment { 'Comment' }
    name { 'Name' }
    post
    user_id { create(:user).id }
  end
end

授权用户的宏:

 module ControllerMacros
  def sign_in_user
    before do
      @user = create(:user)
      @request.env['devise.mapping'] = Devise.mappings[:user]
      sign_in @user
    end
  end
end

所以当我 运行 规范测试时,我得到了这个错误:

 ArgumentError: wrong number of arguments (given 2, expected 0)

可能是什么问题,为什么我不能运行创建rspec?

你这里发生了几件事。该错误是因为您的 let(:post) 记忆助手覆盖了 post 方法的名称。所以,当你调用post :create ...时,它是很不高兴的。因此,您只需要将记忆助手的名称更改为 :post.

以外的名称

第二个问题是你的期望永远不会过去:

expect {{ comment: attributes_for(:comment) } }.to change(Comment, :count).by(1)

当您使用 expect {}...to change() 形式时,RSpec 会逐字检查 expect 块中的内容是否会驱动指定的更改。在您的情况下,expect 块内的代码不会在数据库中创建评论记录,它只是 returns 模拟评论的属性散列,因此它永远不会通过。您确实在上下文块的开头创建了一个新评论,但它不算数,因为它在 expect 块之外。

解决这个问题的一种方法是简单地将 POST 移动到 expect 块中:

RSpec.describe CommentsController, type: :controller do
  let(:user) { create(:user) }
  let(:faux_post) { create(:post) } // Different name to avoid clash

  // ... stuff omitted
  
  describe 'POST #create' do
    context 'with valid attributes' do
      it 'saves the new comment in the database' do
        expect do
          post :create, params: { post_id: faux_post, comment: attributes_for(:comment) }
        end.to change(Comment, :count).by(1)
      end
    end
  end
end