Ruby on rails Rspec和Rails控制器期望值

Ruby on rails Rspec和Rails控制器期望值,ruby-on-rails,rspec,rspec2,Ruby On Rails,Rspec,Rspec2,全部, 测试中存在一些问题,如下所示: 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_

全部,

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

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
这一切都很好,如果我移除控制器,效果也很好。你应该得到期望。如果我把期望留在原地,测试就会失败

奇怪的是,它并没有在一个未满足的期望上失败——它实际上似乎满足了“应该接收”(:某些方法)的期望——只是记录创建和随后的更改评估失败了

问题:

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


谢谢你的帮助

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

因此,控制器的
some_方法将替换为只返回nil的方法。返回nil的before过滤器将停止所有处理。你的行动永远不会被要求

将您的期望更改为:

controller.should_receive(:some_method).once.and_return true
还请注意,您的示例正在测试两件事——确保您的操作调用
some\u方法
,并确保持久化something的数量增加1。这很好,但是如果您真的只想检查后者,您可以使用存根而不是期望值,这更紧凑一些:

controller.stub some_method: true

更新:我应该补充一点,在Rails的最新版本中,控制器过滤器的返回值被忽略。(过滤器可以通过呈现某些内容来阻止操作的执行。)但是,rspec的
应该接收
取代你的方法的原则仍然正确且普遍适用。

一个常见的rspec错误是认为像你的
应该接收
那样的方法期望只是监视应用程序以确保某些事情发生。但实际上,它将自己插入到流中,并完全替换方法

因此,控制器的
some_方法将替换为只返回nil的方法。返回nil的before过滤器将停止所有处理。你的行动永远不会被要求

将您的期望更改为:

controller.should_receive(:some_method).once.and_return true
还请注意,您的示例正在测试两件事——确保您的操作调用
some\u方法
,并确保持久化something的数量增加1。这很好,但是如果您真的只想检查后者,您可以使用存根而不是期望值,这更紧凑一些:

controller.stub some_method: true

更新:我应该补充一点,在Rails的最新版本中,控制器过滤器的返回值被忽略。(过滤器可以通过呈现某些内容来阻止操作的执行。)但是,rspec的
应该接收
替换方法的原则仍然正确且普遍适用。

我现在可以晚上睡觉了。谢谢。我现在可以晚上睡觉了。非常感谢。