【问题标题】:Rspec - post - MassAssignmentSecurity::ErrorRspec - 发布 - MassAssignmentSecurity::Error
【发布时间】:2012-09-07 12:33:07
【问题描述】:

我有几个模型:UserArticle。用户有_many文章,文章属于用户。

我尝试编写测试来检查Post 方法(注意:我在我的应用程序中使用语言环境):

require 'spec_helper'

describe ArticlesController do
  render_views

  before(:each) do
    @admin = FactoryGirl.create( :admin )
    @user  = FactoryGirl.create( :user )
  end

  describe "POST 'create'" do
    before(:each){ @article = FactoryGirl.create(:article) }

    describe "for signed-in admin" do
      before(:each){ test_sign_in( @admin ) }

      it "should create article" do
        expect do
          post :create, :locale => :en, :article => @article.attributes.merge( :content => "some" )
        end.should change( Article, :count ).by(1)
      end
    end
  end
end

但我得到这样的错误:

1) ArticlesController POST 'create' for signed-in admin should create article
     ActiveModel::MassAssignmentSecurity::Error:
       Can't mass-assign protected attributes: id, user_id, created_at, updated_at
     Failure/Error: post :create, :locale => :en, :article => @article.attributes.merge( :content => "some" )
     # ./app/controllers/articles_controller.rb:15:in `create'
     # ./spec/controllers/articles_controller_spec.rb:106:in `block (5 levels) in <top (required)>'
     # ./spec/controllers/articles_controller_spec.rb:105:in `block (4 levels) in <top (required)>'

我该如何解决这个问题?

我的工厂:

FactoryGirl.define do
  factory :user do
    sequence(:email) { |n| "email#{n}@factory.com" }
    password  'qwerty'

    factory :admin do
      admin true
    end
  end

  factory :article do
    content 'text is here'
    user
  end
end

我的控制器:

class ArticlesController < ApplicationController
  before_filter do
    redirect_to :root unless current_user && current_user.admin?
  end

  def create
    @article = Article.new( params[:article] )

    if @article.save
      redirect_to articles_path
      flash[:success] = "It has been created!"
    else
      render 'new'                                                                       
    end
  end
end

文章型号:

# == Schema Information
#
# Table name: articles
#
#  id         :integer          not null, primary key
#  user_id    :integer
#  content    :text
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Article < ActiveRecord::Base
  belongs_to :user

  attr_accessible :content

  validates :content,
              :presence => { :message => :presense_message },
              :length   => {
                             :maximum => 50000,
                             :message => :max_lenght_message
                           }
end

UPD:应用程序在这里:https://github.com/Loremaster/Chirch_app

【问题讨论】:

    标签: ruby rspec ruby-on-rails-3.2 mass-assignment


    【解决方案1】:

    如果不直接测试您的代码,我无法确定,但请尝试更改

    before(:each){ @article = FactoryGirl.create(:article) } 
    

    before(:each){ @article = FactoryGirl.build(:article, :user => @admin) } 
    

    以便您在调用 POST 之前为文章指定作者以及 not saving the article。此外,这条线可能也应该放在您的 describe "for signed-in admin" 块内。

    编辑

    如果您更改测试代码,您的MassAssignmentSecurity::Errors 将消失,以便您build 您的:article 预先 使用your factories 中定义的所有必要参数:

    spec/controllers/articles_controllers.spec

    describe "POST 'create'" do
      before(:each) do
        @article = FactoryGirl.build(:article, :user => @admin, :content => "some")
      end
    
    describe "for non-signed users" do
      it "should deny access" do
        post :create, :locale => :en, :article => @article
        response.should redirect_to( root_path )
      end
    
      it "should not create article" do
        expect do
          post :create, :locale => :en, :article => @article
        end.should_not change( Article, :count )
      end
    end
    
    describe "for signed-in users" do
      before(:each){ test_sign_in( @user ) }
    
      it "should deny access" do
        post :create, :locale => :en, :article => @article
        response.should redirect_to( root_path )
      end
    
      it "should not create article" do
        expect do
          post :create, :locale => :en, :article => @article
        end.should_not change( Article, :count )
      end
    end 
    

    【讨论】:

    • 我尝试了您的解决方案,但没有任何改变。我的错误仍然存​​在。
    • 有一个可以共享的 Github 存储库,以便人们可以自己测试您的代码?
    • 是的,我有 github 帐户。请检查我有问题的更新。
    • 非常感谢您的帮助!但我仍然有管理员的问题。当我尝试这样做时:expect do post :create, :locale =&gt; :en, :article =&gt; @article.attributes.merge(:content =&gt; "some" ) end.should change( Article, :count ).by(1) 它显示:Can't mass-assign protected attributes: id, user_id, created_at, updated_at
    • 我试过了:post :create, :locale =&gt; :en, :article =&gt; @articlepost :create, :locale =&gt; :en, :articles =&gt; { :content =&gt; "some", :title =&gt; "text" }, :user_id =&gt; @admin.id。错误是count should have been changed by 1, but was changed by 0
    猜你喜欢
    • 2012-04-16
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多