2015-10-15 52 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