1. ホーム
  2. ruby-on-rails

[解決済み] rails rspec before all vs before each

2023-07-03 13:05:59

質問

contest_entry_spec.rb

    require 'spec_helper'

    describe ContestEntry do

      before(:all) do
        @admission=Factory(:project_admission)
        @project=Factory(:project_started, :project_type => @admission.project_type)
        @creative=Factory(:approved_creative, :creative_category => @admission.creative_category)
        @contest_entry=Factory(:contest_entry, :design_file_name => 'bla bla bla', :owner => @creative, :project => @project)
      end

      context 'non-specific tests' do
        subject { @contest_entry }
        it { should belong_to(:owner).class_name('User') }
        it { should belong_to(:project) }
        it { should have_many(:entry_comments) }

        it { should validate_presence_of(:owner) }
        it { should validate_presence_of(:project) }
        it { should validate_presence_of(:entry_no) }
        it { should validate_presence_of(:title) }

      end
end

これらのテストを実行すると、すべてが順調ですが、before(:all) を before(:each) に変更すると、すべてのテストが失敗します。

これはエラーです。

 Failure/Error: @contest_entry=Factory(:contest_entry, :design_file_name => 'bla bla bla', :owner => @creative, :project => @project)
     ActiveRecord::RecordInvalid:
       Validation Failed: User is not allowed for this type of project

どのように解決するのですか?

before(:all) は、すべての例が実行される前に、ブロックを一度だけ実行します。

before(:each) は、ファイル中の各スペックが実行される前にブロックを一回実行します。

before(:all) インスタンス変数を設定します @admission, @project, @creative, @contest_entry の前に一度だけ、すべての it ブロックが実行される前に一度だけ実行されます。

しかし :before(:each) が実行されるたびに before ブロックのインスタンス変数がリセットされます。 it ブロックが実行されるたびに、before ブロックのインスタンス変数をリセットします。

微妙な違いですが、重要です。

をもう一度。

before(:all)
#before block is run
it { should belong_to(:owner).class_name('User') }
it { should belong_to(:project) }
it { should have_many(:entry_comments) }

it { should validate_presence_of(:owner) }
it { should validate_presence_of(:project) }
it { should validate_presence_of(:entry_no) }
it { should validate_presence_of(:title) }

before(:each)
# before block
it { should belong_to(:owner).class_name('User') }
# before block
it { should belong_to(:project) }
# before block
it { should have_many(:entry_comments) }
# before block

# before block
it { should validate_presence_of(:owner) }
# before block
it { should validate_presence_of(:project) }
# before block
it { should validate_presence_of(:entry_no) }
# before block
it { should validate_presence_of(:title) }