Rspec tests keep failing with expected … got nil

I'm trying to get into TDD and i'm currently struggling with this error message:

UsersController GET 'show' should find the right user
     Failure/Error: expect(user).to eq(@user)

       expected: #<User id: 1, email: "example@example.com", encrypted_password: "$2a$04$AVGGS0XU1Kjmbdc/iZ86iOq2f4k992boP7xfqcg2nl6...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2014-06-08 19:43:41", updated_at: "2014-06-08 19:43:41", name: "Test User", confirmation_token: nil, confirmed_at: "2014-06-08 19:43:41", confirmation_sent_at: nil, unconfirmed_email: nil, account_id: 1, notify: nil>
            got: nil

       (compared using ==)
     # ./spec/controllers/users_controller_spec.rb:28:in `block (3 levels) in <top (required)>'

Here's the particular test:

require 'rails_helper'
include Devise::TestHelpers

describe UsersController do

  before (:each) do
    @user = FactoryGirl.create(:user)
    sign_in @user
  end

  describe "GET 'show'" do

    it "should find the right user" do
      get :show, :id => @user.id
      puts "user = #{@user.inspect}"
      user = assigns(:user)
      #assigns(:user).should == @user
      puts "assigns user = #{assigns(:user)}"
      expect(user).to eq(@user)
    end

  end

end

Here's the controller:

class UsersController < ApplicationController
...
    def show
        authorize! :show, @user, :message => 'Not authorized as an administrator.'
        @user = current_account.users.find(params[:id])
    end

...
end

application_controller.rb:

class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception

    check_authorization :unless => :devise_controller?
    before_filter :authenticate_user!, :validate_subdomain
    helper_method :subdomain, :current_account
    layout :set_layout

# This will redirect the user to your 404 page if the account can not be found
    # based on the subdomain.  You can change this to whatever best fits your
    # application.
    def validate_subdomain
        current_account
    end

def current_account
        @current_account ||= Account.where(:subdomain => subdomain).first
        #puts @current_account

        if @current_account.nil?
            redirect_to('/accounts/invalid_site')
            return
        end

        @current_account
    end


def subdomain
        request.subdomain
    end

...
end

user factory:

FactoryGirl.define do
  factory :user do
    name 'Test User'
    account_id 1
    email 'example@example.com'
    password 'changeme'
    password_confirmation 'changeme'
    # required if the Devise Confirmable module is used
    confirmed_at Time.now
  end
end

How can I get around this error message? I have a feeling it has something to do with before_filters, but that's just a guess.

Answers


Do you have before_filter on your users controller where you need authentication to use the show method? Your before block is making two calls, creating a user and then "sign_in", some kind of authentication. But your test is just to see if the user was created and the show method returns the correct user record with the passed id.

So I would break down your before block. Start by testing that your Factory is being created successfully:

it 'has a valid factory' do
    FactoryGirl.create(:user).should eq(true) # or should be_valid.. 
end

If that passes, I'd comment out any constraint on your users controller (temporarily) for the sign_in method, and test if show receives the id and returns the correct user.

If that passes, then add the constraint back in for validation on your users controller, and figure out how to test your sign_in method. :)


Ok so i figured it out from debugging through the current_account not getting set. I found this answer Rails rspec set subdomain.

I guess i left out a major piece of the puzzle in my original question so i apologize about that as I had no idea that would affect my rspecs.

The trick was to

before(:each) do
  @account = FactoryGirl.create(:account)
  @request.host = "#{@account.subdomain}.example.com"
end

Need Your Help

Performance loss in VB.net equivalent of light weight conversion from hex to byte

vb.net hex bytearray

I have read through the answers here http://stackoverflow.com/a/14332574/44080

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.