3

私はInvoiceいくつかを含む可能性のあるモデルを持っていますItems:

class Invoice < ActiveRecord::Base

  attr_accessible :number, :date, :recipient, :items_attributes

  belongs_to :user

  has_many :items

  accepts_nested_attributes_for :items, :reject_if => :all_blank, :allow_destroy => true

end

RSpecを使用してこれをテストしようとしています:

describe InvoicesController do

  describe 'user access' do

    before :each do
      @user = FactoryGirl.create(:user)
      @invoice = @user.invoices.create(FactoryGirl.attributes_for(:invoice))
      sign_in(@user)
    end

    it "renders the :show view" do
      get :show
      expect(response).to render_template :show
    end

  end

end

残念ながら、このテスト (および他のすべてのテスト) は、RSpec からの次のエラー メッセージで失敗します。

Failure/Error: @invoice = @user.invoices.create(FactoryGirl.attributes_for(:invoice))
ActiveModel::MassAssignmentSecurity::Error:
Can't mass-assign protected attributes: items

テストに合格したアイテムで請求書を作成するにはどうすればよいですか?

FactoryGirl を使用して、次のようなオブジェクトを作成しています。

factory :invoice do
  number { Random.new.rand(0..1000000) }
  recipient { Faker::Name.name }
  date { Time.now.to_date }
  association :user
  items { |i| [i.association(:item)] } 
end

factory :item do
  date { Time.now.to_date }
  description { Faker::Lorem.sentences(1) }
  price 50
  quantity 2
end
4

2 に答える 2

1

編集:質問を誤解しました。申し訳ありません。

それ以外の

before :each do
  @user = FactoryGirl.create(:user)
  @invoice = @user.invoices.create(FactoryGirl.attributes_for(:invoice))
  sign_in(@user)
end

次のように、ユーザー パラメータで渡された請求書のファクトリを作成するだけです。

before :each do
  @user = FactoryGirl.create(:user)
  FactoryGirl.create :invoice, user: @user
  sign_in(@user)
end

また、これはマイナーなスタイルの提案ですが、インスタンス変数の代わりに、次のように let を使用できます。

let(:user) { FactoryGirl.create :user }

before :each do
  FactoryGirl.create :invoice, user: user
  sign_in(user)
end

請求書の作成に「ユーザー」を渡すと、ユーザーも作成されます (そして、単に「ユーザー」として呼び出すことができます)。

マイナーな警告: 私はこれを約 6 か月間行ってきたので、私のスタイルの提案に同意しない、より知識のある人がいる可能性があります。

于 2013-03-05T19:19:32.960 に答える