RSpec功能测试中块之前的存根

RSpec功能测试中块之前的存根,rspec,functional-testing,stub,Rspec,Functional Testing,Stub,下面的代码示例显示了RSpec手册中关于控制器规格一章中的重构: require 'spec_helper' describe MessagesController do describe "POST create" do it "creates a new message" do message = mock_model(Message).as_null_object Message.should_receive(:new). with("

下面的代码示例显示了RSpec手册中关于控制器规格一章中的重构:

require 'spec_helper'

describe MessagesController do
  describe "POST create" do
    it "creates a new message" do
      message = mock_model(Message).as_null_object
      Message.should_receive(:new).
        with("text" => "a quick brown fox").
        and_return(message)
      post :create, :message => { "text" => "a quick brown fox" }
    end

    it "saves the message" do
      message = mock_model(Message)
      Message.stub(:new).and_return(message)
      message.should_receive(:save)
      post :create
    end

    it "redirects to the Messages index" do
      post :create
      response.should redirect_to(:action => "index")
    end
  end
end

我有几个问题:

1) 我理解使用let块的好处,因为创建和保存的测试都使用mock_模型。然而,我不明白before块的好处。如果只有save测试需要存根,为什么不将代码保留在测试中,而不是将其移动到每个测试之前运行的before块中

2) 更重要的是,before块是否会干扰创建测试所指定的内容?创建测试说,消息应该接收带有一些参数的new,然后使用post:create进行测试。但是,如果before块只是中断了对new的调用,那么在创建测试中,这不是短路了should_接收断言吗?也许我不明白存根和应该如何相互作用

如果只有save测试需要存根

典型的创建操作如下所示:

def create
  @message = Message.new(params[:message])
  if @message.save
    # ... etc. ...
因此,是的,
消息。新的
需要针对每个示例进行存根

如果before块只是中断了对new的调用,那么在创建测试中,这是否会导致should_接收断言短路

事实上,情况正好相反。before块首先运行并存根
:new
,然后运行消息期望并替换存根。您可以删除
之前的
块,并将存根放在其他两个示例的开头,从而获得相同的效果

def create
  @message = Message.new(params[:message])
  if @message.save
    # ... etc. ...