我正在使用Devise和Rspec。所以我有两个名为User and Article的模型,它是文章belongs_to the user
运行rspec
时,我收到一个错误:
1) ArticlesController POST #create with valid attributes saves the article
Failure/Error: post :create, { article: valid_attributes }
#<Double "user"> received unexpected message :articles with (no args)
# ./app/controllers/articles_controller.rb:17:in `create'
# ./spec/controllers/articles_controller_spec.rb:43:in `block (4 levels) in <top (required)>'
以下是我的articles_controller.rb
def new
@article ||= Article.new
render
end
def create
@article = @user.articles.new(article_params)
if @article.save
redirect_to articles_path, notice: "Well done brah! Your article has been publish"
else
render 'new'
end
end
spec/controllers/articles_controller_spec.rb
RSpec.describe ArticlesController, type: :controller do
let(:article) { FactoryGirl.create(:article) }
let (:valid_attributes) { FactoryGirl.attributes_for(:article) }
describe "POST #create" do
context "with valid attributes" do
it "saves the article" do
sign_in
post :create, { article: valid_attributes }
expect(Article.count).to eq(1)
end
end
end
spec/factories/articles.rb
FactoryGirl.define do
factory :article do
title "Article Title"
content "Article Content"
default_image "default_image"
user
category
end
end
我的错误在哪里?我卡在这里
已更新
spec/rails_helper.rb
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
config.include ControllerHelpers, :type => :controller
end
spec/support/controller_helpers.rb
module ControllerHelpers
def sign_in(user = double('user'))
if user.nil?
allow(request.env['warden']).to receive(:authenticate!).and_throw(:warden, {:scope => :user})
allow(controller).to receive(:current_user).and_return(nil)
else
allow(request.env['warden']).to receive(:authenticate!).and_return(user)
allow(controller).to receive(:current_user).and_return(user)
end
end
end
上面的两个更新文件都来自DEvise wiki - https://github.com/plataformatec/devise/wiki/How-To:-Stub-authentication-in-controller-specs
答案 0 :(得分:2)
您需要为您的用户*使用实际的数据库记录。
RSpec.describe ArticlesController, type: :controller do
let(:article) { FactoryGirl.create(:article) }
let(:valid_attributes) { FactoryGirl.attributes_for(:article) }
let(:user) { FactoryGirl.create(:user) }
let(:valid_session) { sign_in(user) }
describe "POST #create" do
before { valid_session }
context "with valid attributes" do
it "saves the article" do
# less prone to false positives
expect do
post :create, { article: valid_attributes }
end.to change(Article, :count).by(1)
end
end
end
end
我们使用expect {}.to change
,因为如果没有正确清理数据库,您可能会误报。
Devise::TestHelpers
已有sign_in
个功能。因此,请删除您的ControllerHelpers
模块,以便您的项目不会与Devise或Warden内部链接。