我对嵌套对象(注释(进行了rspec测试,它嵌套在posts对象中。这是路线。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
这里是rsspec测试:
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)
可能是什么问题,为什么我不能运行CREATE rspec?
这里有几件事。该错误是因为let(:post)
内存化帮助程序正在重写post
方法的名称。所以,当你打电话给post :create ...
时,它非常不高兴。因此,您只需要将已存储助手的名称更改为:post
以外的名称。
第二个问题是你的期望永远不会过去:
expect {{ comment: attributes_for(:comment) } }.to change(Comment, :count).by(1)
当您使用expect {}...to change()
表单时,RSpec会检查expect
块中的内容是否会驱动指定的更改。在您的情况下,expect块内的代码不会在数据库中创建Comment记录,它只是返回模拟Comment的属性哈希,因此它永远不会通过。您确实在上下文块的开头创建了一个新的Comment,但它不计算在内,因为它在expect
块之外。
解决这个问题的一种方法是简单地将POST移动到预期块:
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