Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoMethodError: undefined method `email' for nil:NilClass (Rspec/factory girl/cancan/devise)

I am following Hartl's Rails tutorial but I used devise/cancan/rolify so some things are not the same.

On my users_pages_spec.rb test, I keep getting this error in spite of all I tried:

1) User pages index delete links as an admin user 
 Failure/Error: sign_in @superadmin
 NoMethodError:
   undefined method `email' for nil:NilClass
 # ./spec/support/utilities.rb:14:in `sign_in'
 # ./spec/requests/user_pages_spec.rb:91:in `block (5 levels) in <top (required)>'

2) User pages index delete links as an admin user 
 Failure/Error: sign_in @superadmin
 NoMethodError:
   undefined method `email' for nil:NilClass
 # ./spec/support/utilities.rb:14:in `sign_in'
 # ./spec/requests/user_pages_spec.rb:91:in `block (5 levels) in <top (required)>'

3) User pages index delete links as an admin user should be able to delete another user
 Failure/Error: sign_in @superadmin
 NoMethodError:
   undefined method `email' for nil:NilClass
 # ./spec/support/utilities.rb:14:in `sign_in'
 # ./spec/requests/user_pages_spec.rb:91:in `block (5 levels) in <top (required)>'

4) User pages index delete links as an admin user 
 Failure/Error: sign_in @superadmin
 NoMethodError:
   undefined method `email' for nil:NilClass
 # ./spec/support/utilities.rb:14:in `sign_in'
 # ./spec/requests/user_pages_spec.rb:91:in `block (5 levels) in <top (required)>'

I don't understand why, does nil::nilClass mean factory girl actually does not manage to create this superadmin user?

Here is the sample of my user_pages_spec.rb file:

require 'spec_helper'
require 'cancan/matchers'

# Test if targeted words appears in displayed content

describe "User pages" do

subject { page }
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") }
let(:non_admin) { FactoryGirl.create(:user) }
let(:submit) { "Sign in" }

describe "index" do
  describe "delete links" do

  it { should_not have_link('delete') }

  describe "as an admin user" do
    let(:superadmin) { FactoryGirl.create(:superadmin) }
    before do
      sign_in @superadmin
      visit users_path
    end
    it { should have_title('List of users') }

    it { should have_link('delete', href: user_path(User.first)) }
    it "should be able to delete another user" do
      expect { click_link('delete') }.to change(User, :count).by(-1)
    end
    it { should_not have_link('delete', href: user_path(superadmin)) }
  end
end
end
end

my spec/utilities.rb defining sign_in method

include ApplicationHelper

def sign_in(user)
visit new_user_session_path
fill_in "Email",        with: user.email
fill_in "Password", with: user.password
click_button "Login"
#populate cookie when not using capybara
cookies[:authentication_token] = user.authentication_token
end

and my spec/factories/user.rb

FactoryGirl.define do
factory :user do
sequence(:name)  { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}@example.com"}   
password "beta"
password_confirmation "beta"
# required if the Devise Confirmable module is used
confirmed_at Time.now
confirmation_token nil

factory :superadmin do
  after(:create) {|user| user.add_role(:superadmin)}
end
end

end

I do have in cancan/rolify a superadmin role defined.

If anybody has a clue, I'd take it! i can update the question with additional file needed if not already here.

like image 430
Mathieu Avatar asked Dec 06 '25 00:12

Mathieu


1 Answers

Your let call is setting superadmin, but you're referencing @superadmin, which is going to be nil, since it hasn't been set. BTW, this is a good reason to generally avoid using instance variables in your tests, as they silently default to nil when referenced if uninitialized.

like image 83
Peter Alfvin Avatar answered Dec 08 '25 13:12

Peter Alfvin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!