【问题标题】:Rspec and Rails Controller ExpectationsRspec 和 Rails 控制器的期望
【发布时间】:2012-04-17 02:48:25
【问题描述】:

全部,

在测试中遇到一些问题,如下所示:

it "does something" do
  controller.should_receive(:some_method).once

  expect {
    post :create, some_params_hash, some_session_hash
  }.to change(Something, :count).by(1)
end

导轨一侧的控制器 - 粗略示例:

class SomethingsController
  before_filter :some_method

  def create
    respond_with Something.create params[:something]
  end

  def some_method
    puts 'some_method'
  end
end

这一切都很好,并且工作得很好如果我删除了 controller.should_receive 期望。如果我保持期望 - 测试失败。

奇怪的是它并没有因为不满足的期望而失败——它实际上似乎满足了 should_receive(:some_method) 的期望——只是记录创建和随后的变更评估失败了。

所以 - 问题:

这是在作为测试的一部分调用的控制器上指定期望的正确方法吗?

感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails rspec rspec2


    【解决方案1】:

    一个常见的 rspec 错误是认为像您的 should_receive 设置的方法期望只是监视应用程序以确保某些事情发生。但实际上它会将自己插入到流程中并替换整个方法。

    所以你的控制器 some_method 将被替换为只返回 nil 的控制器。返回 nil 的 before 过滤器将停止所有处理。您的操作永远不会被调用。

    改变你的期望:

    controller.should_receive(:some_method).once.and_return true
    

    还请注意,您的示例正在测试两件事 - 它确保您的操作调用 some_method 并确保持久的Somethings 的数量增加一。没关系,但如果你真的只打算检查后者,你可以使用存根而不是期望,这样更紧凑:

    controller.stub some_method: true
    

    更新:我应该补充一点,在最新版本的 Rails 中,控制器过滤器的返回值被忽略了。 (过滤器可以通过渲染一些东西来阻止动作执行。)但是,rspec的should_receive替换你的方法的原理仍然是正确的,并且普遍适用。

    【讨论】:

    • 我现在可以晚上睡觉了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    相关资源
    最近更新 更多