我有一个令人困惑的 rSpec 问题 - 取决于我编写代码的方式,描述“失败”规范的测试失败或描述“成功”规范的测试失败。
以下是创建操作的测试:
describe "POST 'create'" do
describe "failure" do
before(:each) do
@attr = {name: "", type_of_group: ""}
@student_attr = [{name: "Joe", gender: "Male"}, {name: "sally twotrees", gender: "Female"}]
@create = post :create, student_group: @attr, student: @student_attr
end
it "should have the right title" do
@create
response.should have_selector('title', :content => "Create a new group" )
end
it "should render the 'new' page" do
@create
response.should render_template('new')
end
it "should not create a user" do
lambda do
post :create, student_group: @attr
end.should_not change {@user.student_groups.count}
end
it "should flash an error message" do
@create
flash[:error].should =~ /please/i
end
end
describe "success" do
before(:each) do
@attr = FactoryGirl.attributes_for(:student_group)
# @student_attr = {name: "test", gender: "Male"}
end
it "should create a student_group" do
lambda do
post :create, student_group: @attr
end.should change {@user.student_groups.count}.by(1)
end
it "should create students" # do
# lambda do
# post :create, student_group: @attr, student: @student_attr
# end.should change {@student_groups.students.count}.by(1)
# end
it "should flash a success message" do
post :create, student_group: @attr
flash[:success].should =~ /has been added/i
end
it "should redirect" do
post :create, student_group_id: @group, student_group: @attr
response.should be_redirect
end
end
end
所有“失败”测试都因以下错误而失败:
Failure/Error: @create = post :create, student_group: @attr, student: @student_attr
ActionView::Template::Error:
`@student_group[students_attributes]' is not allowed as an instance variable name
如果我以这种方式在控制器中编写代码:
def create
@params = params[:student_group][:students_attributes]
@student_group = @user.student_groups.build(params[:student_group])
if @student_group.save
### RE: 'defensive coding' https://stackoverflow.com/questions/14502508/undefined-method-for-nilnilclass-when-pushing-values-to-an-array
if @params.present?
### https://stackoverflow.com/questions/11355820/rails-3-2-iterate-through-an-array
@params.each do |student|
@student_group.students.create(name:"#{student[:name]}", gender: "#{student[:gender]}")
end
end
# new subject path
redirect_to class_path(@student_group), flash: { success: "#{@student_group.name} has been added successfully" }
else
@title = "Create a new group"
flash.now[:error] = "Something's gone wrong. Please try again!"
render 'new'
end
end
如果控制器代码是这样编写的,那么所有的“成功”测试都会失败:
def create
@params = params[:student_group][:students_attributes]
@student_group = @user.student_groups.build(params[:student_group])
### http://railsforum.com/viewtopic.php?pid=40056#p40056
if @params.present?
@student = Student.new
else
@student = @student_group.students.build(@params)
end
if @student_group.save
### RE: 'defensive coding' https://stackoverflow.com/questions/14502508/undefined-method-for-nilnilclass-when-pushing-values-to-an-array
if @params.present?
### https://stackoverflow.com/questions/11355820/rails-3-2-iterate-through-an-array
@params.each do |student|
@student_group.students.create(name:"#{student[:name]}", gender: "#{student[:gender]}")
end
end
# new subject path
redirect_to class_path(@student_group), flash: { success: "#{@student_group.name} has been added successfully" }
else
@title = "Create a new group"
flash.now[:error] = "Something's gone wrong. Please try again!"
render 'new'
end
end