2

他のテーブルの外部キーを保持するモデルTeacherLeaderがあります。このテーブルを更新して、コントローラーのテストを (rspec 経由で) 書き込もうとします。

私のモデル:

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

しかし、私のアプリケーションは動作します! 私は間違ったテストで何をしますか?

4

2 に答える 2

6

コントローラーはparams[:teacher_leader]ハッシュを期待していますが、テストはハッシュを提供していません。これを試して:

it "should update teacher leader with correct params" do
  put :update, :id => @teacher_leader, :teacher_leader => { :teacher_id => @teacher.id }
  # ...
于 2012-04-07T12:37:38.757 に答える
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

于 2012-04-07T12:41:51.127 に答える