我有模型 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)>'
但我的申请有效!我在测试中做错了什么?
答案 0 :(得分:6)
您的控制器需要params[:teacher_leader]
哈希,但您的测试不提供它。试试这个:
it "should update teacher leader with correct params" do
put :update, :id => @teacher_leader, :teacher_leader => { :teacher_id => @teacher.id }
# ...
答案 1 :(得分: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 }
无论如何,我强烈建议您在控制器规范中模拟所有数据库查询(活动记录调用)。为了测试params是否持久化,您应该使用请求规范(或其他方法进行集成/验收测试)。例如,请参阅:http://blog.bandzarewicz.com/slides/krug-the-perfect-rspec/#27