Search code examples
ruby-on-railsrspec

rails rspec before all vs before each


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

When I run these tests everything is okey but if I change before(:all) to before(:each) every test will be failed.I don't know why it happens?

This is the error

 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

Solution

  • before(:all) runs the block one time before all of the examples are run.

    before(:each) runs the block one time before each of your specs in the file

    before(:all) sets the instance variables @admission, @project, @creative, @contest_entry one time before all of the it blocks are run.

    However, :before(:each) resets the instance variables in the before block every time an it block is run.

    Its a subtle distinction but important

    again,

    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) }