2015-10-15 49 views
0

我正在用Rspec使用Devise。所以,我已經兩個示範叫用戶和文章這是文章belongs_to的用戶Rspec測試失敗,出現意外的消息:文章

當運行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 

兩個更新的文件上面,我從設計維基得到它 - https://github.com/plataformatec/devise/wiki/How-To:-Stub-authentication-in-controller-specs

+0

錯誤不在您提供的代碼中。在您的測試設置中的某處,您爲用戶注入了一個雙精度值。我在你的'sign_in'方法中猜測它。 請包括您的'spec/rails_helper.rb'的相關部分以及您擁有的任何與會話相關的測試助手。 – max

+0

@max我已經更新了我的問題 – AmirolAhmad

回答

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內部。

+0

*好吧,你可以設置雙重假數據庫所有的交互,但這不會是一個很好的測試,因爲你可能會掩蓋錯誤。 – max

+0

噢,它很好地工作...感謝您的幫助建議..將刪除''''ControllerHellper''''然後..非常感謝 – AmirolAhmad