2

我有模型TeacherLeader它爲其他表保留外鍵。我可以更新這張表,我嘗試爲我的控制器編寫測試(通過rspec)。Rails 3 - 通過rspec正確測試PUT方法

我的模型:

# 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 

我控制器

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 

所以,我有寫作試驗PUT問題。這裏是例如我的代碼PUT方法:

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 

當我嘗試運行我的規格,我得到的是:

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)>' 

但我的應用程序的工作!我在測試中做什麼錯了?

+0

可能是'put:update,:id => @ teacher_leader.id,...''? – MikDiet 2012-04-07 12:39:01

回答

6

您的控制器期望有一個params[:teacher_leader]散列,但您的測試不提供它。試試這個:

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

確保您的規格是否包含describe TeacherLeadersController塊。例如:

describe TeacherLeadersController do 
    describe "PUT 'update" do 
    #... 

    describe "for signed-in school-heads" do 
     it "should update teacher leader with correct params" do 
     put :update, :id => @teacher_leader, :teacher_id => @teacher.id 
     end 
    end 
    end 
end 

..然後您應該可以正確使用put方法。

此外,您忘了將:teacher_leader屬性傳遞給測試中的控制器。嘗試put :update, :id => something, :teacher_leader => { some_attributes_here }

無論如何,我強烈建議您在控制器規格中模擬所有數據庫查詢(活動記錄調用)。爲了測試參數是否持久,您應該使用請求規格(或其他進行集成/驗收測試的方法)。例如:http://blog.bandzarewicz.com/slides/krug-the-perfect-rspec/#27