RSpec控制器规范在使用无效参数更新时失败

时间:2015-12-11 18:17:16

标签: ruby-on-rails ruby-on-rails-4 rspec

脚手架生成的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

因此,应该呈现“编辑”模板的断言永远不会成立,并且具有无效参数的更新操作的默认控制器规范将永远不会变为绿色。

我在这里缺少什么?

2 个答案:

答案 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这样的未知范围被忽略,控制器会成功执行操作。