Rspec测试因意外消息而失败:文章

时间:2015-10-15 10:09:38

标签: ruby-on-rails ruby ruby-on-rails-4 rspec devise

我正在使用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

1 个答案:

答案 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内部链接。