2

Ich habe Modell TeacherLeader, die Fremdschlüssel für andere Tabellen hält. Ich kann diese Tabelle aktualisieren und versuche, Tests für meinen Controller zu schreiben (über rspec).Schienen 3 - richtigen Test für PUT-Methode über RSPEC

Mein Modell:

# 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 

Mein 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 

Also, habe ich Probleme mit dem Schreiben von Tests für PUT. Hier ist Beispiel für meinen Code für PUT-Methode:

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 

Wenn ich versuche, meine Brille zu laufen bekomme ich das:

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

Aber meine Anwendung funktioniert! Was mache ich in Tests falsch?

+0

Kann 'put: update,: id => @ teacher_leader.id, ...'? – MikDiet

Antwort

6

Ihr Controller erwartet einen params[:teacher_leader] Hash, aber Ihr Test liefert diesen nicht. Versuchen Sie folgendes:

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

Vergewissern Sie sich, ob Ihre Angaben mit describe TeacherLeadersController Block gewickelt werden. Zum Beispiel:

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 

..then sollten Sie in der Lage sein, richtig put Methode zu verwenden.

Auch Sie haben vergessen, :teacher_leader Attribute an den Controller unter dem Test zu übergeben. Versuchen Sie put :update, :id => something, :teacher_leader => { some_attributes_here }

Wie auch immer, ich empfehle Ihnen dringend, alle Datenbankabfragen (aktive Datensatzaufrufe) in den Controller-Spezifikationen zu verspotten. Um zu testen, ob Parameter beibehalten werden, sollten Sie Anforderungsspezifikationen (oder eine andere Methode für Integrations-/Akzeptanztests) verwenden. Siehe zum Beispiel: http://blog.bandzarewicz.com/slides/krug-the-perfect-rspec/#27