Topic: Error: undefined method for nil:NilClass

When I test functionals, I get the following error:

test_should_display_index(AlertsControllerTest):
ActionView::TemplateError: undefined method `name' for nil:NilClass
    On line #9 of app/views/alerts/index.html.erb
    
        6: 
        7: <tr class="<%= row_class %>">
        8:      <td scope="row" class="first odd"><%=h alert.title %></td>
        9:      <td class="even"><%=h alert.file_status.name %></td>
        10:     <td class="last odd"><%= render :partial => "shared/action_links", :locals => { :obj => alert, :type => "alert" } %>
        11:     </td>
        12: </tr>

This test should confirm the proper display of the index for class Alerts.  Alerts belong to class FileStatuses.  Each file_status contains two objects: :id and :name.

<%=h alert.file_status.name %>

produces the expected result when viewed in a browser (either `draft`, `published` or `trash` depending on the individual alert's setting). So it seems that the only thing finding this error is the test.

The test is pretty straight forward.  Its code is:

class AlertsControllerTest < ActionController::TestCase

  test "should display index" do
    get :index
    assert_response :success
    assert_template 'index'
    assert_not_nil assigns(@alert)
  end
end

So what am I doing wrong?

Last edited by kingjeffrey (2010-02-19 19:45:37)

Re: Error: undefined method for nil:NilClass

OK, I figured it out.  I just needed to populate my fixtures (in /tests/fixtures/). There is a good videocast addressing how to represent these relationships here: http://railscasts.com/episodes/81-fixtures-in-rails-2-0

Re: Error: undefined method for nil:NilClass

Nice one! Ya, running tests always uses a fresh test database and populates the fixtures. Gets me from time to time as well. You may also want to check out alternatives to fixtures such as machinist (http://github.com/notahat/machinist) or factory_girl (http://github.com/thoughtbot/factory_girl).

Re: Error: undefined method for nil:NilClass

I'm having pretty much the same problem (the same error at least), so I thought I'd use this thread rather than clutter the forum with similar posts....

I have already populated my fixtures though and I know they are being loaded into my functional test correctly, but for some reason I keep getting the following error when trying to use a fixture record in a simulated post request:

"NoMethodError: undefined method `screen_name' for nil:NilClass"

Here are the relevant parts of my code:

user_controller.rb

  def login
    @title = 'Log in to RailsSpace'
    if request.post? and params[:user]
      @user = User.new(params[:user])
      user = User.find_by_screen_name_and_password($user.screen_name, @user.password)
      if user
        session[:user_id] = user.id
        flash[:notice] = "User #{user.screen_name} logged in!"
        redirect_to :action => 'index'
      else
        # Don't show the password in the view
        @user.password = nil
        flash[:notice] = "Invalid screen name/password combination"
      end
    end
  end

users.yml

valid_user:
  screen_name: millikan
  email: ram@example.com
  password: electron

invalid_user:
  screen_name: aa/noyes
  email: anoyes@example,com
  password: sun

and user_controller_test.rb

  def setup
    # This user is initially valid, but we may change its attributes
    @valid_user = users(:valid_user)
  end

  # Test a valid login
  test "login success" do
    # assert_equal 'test', @valid_user.screen_name, "Valid user's screen name is: #{@valid_user.screen_name}"
    post :login, :user => { :screen_name => @valid_user.screen_name, :password => @valid_user.password }
    assert_not_nil session[:user_id]
    assert_equal @valid_user.id, session[:user_id]
    assert_equal "User #{@valid_user.screen_name} logged in!", flash[:notice]
    assert_redirected_to :action => 'index'
  end

When I wasn't sure that the @valid_user record was being loaded from my fixture I created the (now commented out) test to deliberately fail and show me what this variable contains.  The output was "Valid user's screen name is: millikan", so the fixture is definitely being loaded.  Can anyone suggest why I might be getting the undefined method 'screen_name' error on the line where I am making the post request?  I've been working on this for hours now and can't seem to figure it out.

By the way, I'm currently working using rails 3.0beta, could this be a bug or am I doing something wrong?  Thanks!

Last edited by MastahUK (2010-03-07 14:53:52)

Re: Error: undefined method for nil:NilClass

Sorry, I've resolved this problem myself now.  After all this time it turns out it was just a typo in my users controller....d'oh!  I'd accidentally written $user.screen_name instead of @user.screen_name.  I'll blame my PHP background for that one!

Re: Error: undefined method for nil:NilClass

I'll admit I didn't read this whole message, but I wonder if it could really be as simple as that you have this:

user = User.find_by_screen_name_and_password($user.screen_name, @user.password)

instead of this:

user = User.find_by_screen_name_and_password(@user.screen_name, @user.password)

Re: Error: undefined method for nil:NilClass

Yep you got it in one, but unfortunately were roughly 26 minutes too late! tongue

I can't wait until I'm not such a noob at this rails malarkey and can debug stupid mistakes like this with relative ease.  But until then, I expect I'll be frequenting this forum a fair bit!

Re: Error: undefined method for nil:NilClass

If you ever figure out how to NOT make silly typos, be sure to let me know. I haven't figured that part out yet, and don't know anybody who hasn't spent hours looking for a stray comma/semicolon/end/period/whatever.