RSpec之前(:每个)拒绝玩好

时间:2014-11-20 03:19:07

标签: ruby-on-rails rspec factory-bot

之前的RSpec:每个循环对我来说真的是一个问题,因为它似乎不想应用于每个块,而只是想要应用于它的前面。这是我的整个spec文件:

require 'rails_helper'

DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean

RSpec.describe User, :type => :model do

  describe "(1) Has Associations and Test Data" do
    context "(a) has a valid factory" do 
      it { expect(build(:user)).to be_valid }
    end

    context "(b) belongs to a company" do 
      it { expect(User.reflect_on_association(:company).macro).to eq(:belongs_to) }
    end

    context "(c) has many shifts" do 
      it { expect(User.reflect_on_association(:shifts).macro).to eq(:has_many) }
    end
  end

  describe "(2) JSON API Methods for current_user" do

    before(:each) do  
      DatabaseCleaner.clean
      @user = FactoryGirl.create(:user)
      @schedule = FactoryGirl.create(:schedule)
      @shift = FactoryGirl.create(:shift, user_id: @user.id, schedule_id: @schedule.id)
    end

    context ".shifts returns all shifts" do
      #it { expect(@user.shifts).to eq(Shift.where(:user_id => @user.id)) }
      it { expect(@user.shifts).to include @shift }
    end

    context ".last_weeks_shifts returns all shifts for LAST week" do 
      last_weeks_schedule = FactoryGirl.create(:schedule, week_num: Date.today.cweek - 1).id
      last_weeks_shift = @shift.update_attributes(schedule_id: last_weeks_schedule)
      it { expect(@user.last_weeks_shifts).to include last_weeks_shift}
    end

    context ".this_weeks_shifts returns all shifts for THIS week" do 
      it { expect(@user.this_weeks_shifts).to equal [] }
    end

    context ".next_weeks_shifts returns all shifts for NEXT week" do 
      it { expect(@user.next_weeks_shifts).to equal [] }
    end

    context ".shift_today? returns true if it has a shift today" do 
      it { expect(@user.shift_today?).to equal true or false }
    end
  end
end

作为参考,具体来说这是我的问题:

before(:each) do  
  DatabaseCleaner.clean
  @user = FactoryGirl.create(:user)
  @schedule = FactoryGirl.create(:schedule)
  @shift = FactoryGirl.create(:shift, user_id: @user.id, schedule_id: @schedule.id)
end

context ".shifts returns all shifts" do
  #it { expect(@user.shifts).to eq(Shift.where(:user_id => @user.id)) }
  it { expect(@user.shifts).to include @shift }
end

context ".last_weeks_shifts returns all shifts for LAST week" do 
  last_weeks_schedule = FactoryGirl.create(:schedule, week_num: Date.today.cweek - 1).id
  last_weeks_shift = @shift.update_attributes(schedule_id: last_weeks_schedule)
  it { expect(@user.last_weeks_shifts).to include last_weeks_shift}
end

如果我调用binding.pry并在最后一个上下文块中检查我的对象,这是我的结果:

[1] pry(#<Class>)> @shift
nil
[2] pry(#<Class>)> @schedule
nil
[3] pry(#<Class>)> @user
nil

为什么我在before循环中设置的对象消失了?请注意它们是实例变量。

1 个答案:

答案 0 :(得分:1)

请参阅rspec before(:each) using factorygirl to create model not working

表示对象的实例变量在实际测试之前不会实例化。除非你测试它,否则@shift将不存在,因此使用let:

要好得多
let(:user) { FactoryGirl.create(:user) }
let(:schedule) { FactoryGirl.create(:schedule) }
let(:shift) { FactoryGirl.create(:shift, user_id: user.id, schedule_id: schedule.id) }

before(:each) do  
  DatabaseCleaner.clean
end