2

J'ai le modèle TeacherLeader qui conserve les clés étrangères pour les autres tables. Je peux mettre à jour cette table et j'essaye d'écrire des tests pour mon contrôleur (via rspec).Rails 3 - test correct pour la méthode PUT via rspec

Mon modèle:

# 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 

Mon contrôleur

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 

, j'ai des problèmes avec des tests d'écriture pour PUT. Voici exemple de mon code pour la méthode 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 

Quand je tente d'exécuter mes specs je reçois que:

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

Mais mes travaux d'application! Qu'est-ce que je fais dans les tests mal?

+0

Peut être 'put: update,: id => @ teacher_leader.id, ...'? – MikDiet

Répondre

6

Votre contrôleur s'attend à un hachage params[:teacher_leader], mais votre test ne le fournit pas. Essayez ceci:

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

Assurez-vous que si vos spécifications sont enveloppées avec describe TeacherLeadersController bloc. Par exemple:

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 vous devriez être en mesure d'utiliser correctement put méthode.

Vous avez également oublié de transmettre les attributs :teacher_leader au contrôleur lors du test. Essayez put :update, :id => something, :teacher_leader => { some_attributes_here }

De toute façon, je vous recommande fortement de se moquer de toutes les requêtes de base de données (appels d'enregistrement actifs) dans les spécifications du contrôleur. Pour tester si les paramètres sont persistants, vous devez utiliser les spécifications des requêtes (ou d'autres méthodes pour effectuer des tests d'intégration/d'acceptation). Voir par exemple: http://blog.bandzarewicz.com/slides/krug-the-perfect-rspec/#27