Search code examples
ruby-on-rails-3model-view-controllermodelrspecrspec-rails

Rails 3 - correct test for PUT method via rspec


I have model TeacherLeader which keeps foreign keys for other tables. I can update this table and i try to write tests for my controller (via rspec).

My model:

#  id         :integer         not null, primary key
#  user_id    :integer
#  teacher_id :integer
#

class TeacherLeader < ActiveRecord::Base  
  belongs_to :user
  belongs_to :teacher

  validates :teacher_id, 
              :uniqueness => { :message => "already a class-head" }
end

My controller

class TeacherLeadersController < ApplicationController
 def edit
    @teacher_leader = TeacherLeader.find( params[:id] )    
    ...
  end

  def update
    @teacher_leader = TeacherLeader.find( params[:id] )
    ...

    if ( @teacher_leader.update_attributes( params[:teacher_leader] ) )                   
      redirect_to teachers_path
      ...
    else
      redirect_to edit_teacher_leader_path
      ...
      end      
    end
  end
end

So, i have problems with writing tests for PUT. Here is example of my code for PUT method:

describe TeacherLeadersController do
  render_views

  before(:each) do    
    @teacher = Factory( :teacher )
    @teacher.user.user_role = "teacher"
    @teacher.save!

    @user = Factory( :user, :user_login => Factory.next(:user_login) )
    @user.user_role = "class_head"
    @user.save!

    @sh = Factory( :user, :user_login => Factory.next(:user_login)  )
    @sh.user_role = "school_head"
    @sh.save!
  end

  describe "PUT 'update" do
    before(:each) do
      @teacher_leader = @user.create_teacher_leader( @attr_teacher_leader )
    end

    describe "for signed-in school-heads" do
      before(:each) do
        test_sign_in( @sh )
      end

      it "should update teacher leader with correct params" do
        put :update, :id => @teacher_leader, :teacher_id => @teacher.id
        @teacher_leader.reload
        @teacher_leader.teacher_id.should  == @teacher.id
      end
    end
  end
end

When i try to run my specs i get that:

1) TeacherLeadersController PUT 'update for signed-in school-heads should update teacher leader with correct params
     Failure/Error: put :update, :id => @teacher_leader, :teacher_id => @teacher.id
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # ./app/controllers/teacher_leaders_controller.rb:57:in `update'
     # ./spec/controllers/teacher_leaders_controller_spec.rb:150:in `block (4 levels) in <top (required)>'

But my application works! What do i do in tests wrong?


Solution

  • Your controller is expecting a params[:teacher_leader] hash, but your test doesn't supply it. Try this:

    it "should update teacher leader with correct params" do
      put :update, :id => @teacher_leader, :teacher_leader => { :teacher_id => @teacher.id }
      # ...