脚手架生成的RSpec控制器规范中的一个测试失败了,它看起来好像它必须总是在设计上失败,但当然它肯定会成功。
我使用rails g scaffold
生成的RSpec规范开发了一个Rails 4应用程序。
我的SkillsController
的控制器规范要求我为我的模型填写“有效属性”哈希和“无效属性”哈希,我做了。
测试所有成功除了“PUT更新,无效参数重新渲染'编辑'模板”:
1) SkillsController PUT update with invalid params re-renders the 'edit' template
Failure/Error: expect(response).to render_template("edit")
expecting <"edit"> but rendering with <[]>
# ./spec/controllers/skills_controller_spec.rb:139:in `block (4 levels) in <top (required)>'
在Rails控制台中,我确认我的invalid_params
哈希包含无效参数({ hack: 'hack' }
)。
控制器调用返回空哈希的skill_params
方法,因为我的invalid_params
哈希只包含无效参数。
使用空skill.update(skill_params)
哈希调用skill_params
返回true,以便else
部分永远不会执行,并且'new'模板将不会呈现:
def update
respond_to do |format|
if @skill.update(skill_params) # empty hash due to invalid params!
format.html { redirect_to @skill, notice: 'Skill was successfully updated.' }
format.json { render :show, status: :ok, location: @skill }
else
format.html { render :edit }
format.json { render json: @skill.errors, status: :unprocessable_entity }
end
end
end
总结:规范将带有无效参数的哈希PUT输出到我的SkillController。 SkillController的'skill_params'清除此哈希值,返回空哈希值。带有空哈希的skill.update
是无操作(在控制台上确认),该方法返回true
。
因此,应该呈现“编辑”模板的断言永远不会成立,并且具有无效参数的更新操作的默认控制器规范将永远不会变为绿色。
我在这里缺少什么?
答案 0 :(得分:4)
我终于明白并在这里发布解决方案,以防其他人发现自己处于相同的情况。
'无效参数'散列不是关于具有无效属性名称的参数,而是关于无效属性值的更多信息。
无效的属性名称被简单地忽略/丢弃,正如@Simone Carletti在回复中指出的那样。
如果无效的值是PUT到控制器,mymodel.update
方法将返回false,控制器将重定向到:edit动作。
因此,为了使生成的规范通过,spec文件顶部的“无效属性”散列应填充有效的属性名称和无效的属性值(例如,如果需要属性,则为nil)。
答案 1 :(得分:3)
这是你应该期待的。使用强参数时,返回的哈希仅包含您明确允许的属性。
这意味着如果您不允许使用hack
参数,那么如果您使用
{ hack: 'hack' }
skill_params
的结果将是
{}
按照设计,update
非常乐意接受空哈希。因此,如果您执行
@skill.update({})
结果为true,因为执行成功。当然,它没有做任何事情,但它没有失败。
因此,您的控制器将默默地成功,并且不会运行edit
条件。
我不明白为什么你会期望传递“未处理”的参数会导致控制器显示编辑页面。它每天都在发生。只需随机站点并随机附加查询字符串即可。例如,转到
http://stackoverflow.com/?tab=interesting
并附加随机查询字符串
http://stackoverflow.com/?tab=interesting&foo=bar
页面很乐意忽略它。它不会渲染错误,也不会崩溃。您的控制器也会发生同样的情况,hack
这样的未知范围被忽略,控制器会成功执行操作。