starwars25
starwars25

Reputation: 405

Why instance variable in rspec is nil?

I have this code:

  before(:all) { @user = FactoryGirl.create(:user)}
  byebug
  subject { @user }
  it { should respond_to(:email)}
  it { should respond_to(:password)}
  it { should respond_to(:password_confirmation)}


  it { should be_valid }

  it { should validate_presence_of(:email) }

  it { should validate_confirmation_of(:password) }
  it { should allow_value('[email protected]').for(:email)}

  describe 'validations' do
    subject { FactoryGirl.create(:user)}
    it { should validate_uniqueness_of(:email).case_insensitive}
  end

When it stops after byebug, it discovers that @user is nil:

    1: require 'rails_helper'
    2: 
    3: describe User do
    4:   before(:all) { @user = FactoryGirl.create(:user)}
    5:   byebug
=>  6:   subject { @user }
    7:   it { should respond_to(:email)}
    8:   it { should respond_to(:password)}
    9:   it { should respond_to(:password_confirmation)}
   10: 
(byebug) display @user
1: @user = nil
(byebug) 

Why is it happening? If I change FactoryGirl to User.create, nothing changes.

Upvotes: 1

Views: 753

Answers (2)

spickermann
spickermann

Reputation: 106792

in your example

before(:all) { @user = FactoryGirl.create(:user)}
byebug
subject { @user }

@user is nil, because byebug interrupts on the level of the definition of the test, not the actual run of the test.

Change it to:

before(:all) { 
  @user = FactoryGirl.create(:user) 
  byebug
}
subject { @user }

Btw: you can just write the following to avoid database access and to make the specs faster:

subject { FactoryGirl.build(:user) }

Upvotes: 3

Rubyrider
Rubyrider

Reputation: 3587

Change the line from

before(:all) { @user = FactoryGirl.create(:user)}

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

remove subject. Now inspect, you will receive user object in user variable. This is the best practice.

Upvotes: 1

Related Questions