【问题标题】:Stub, Should_Receive, and Before Blocks in RSpec Functional TestsRSpec 功能测试中的 Stub、Should_Receive 和 Before 块
【发布时间】:2012-11-02 04:02:19
【问题描述】:

下面的代码示例显示了 RSpec Book 中控制器规范一章的重构:

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

require 'spec_helper'

describe MessagesController do
  describe "POST create" do
    let(:message) { mock_model(Message).as_null_object }

    before do
      Message.stub(:new).and_return(message)
    end

    it "creates a new message" do
      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.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_model。但是,我不明白 before 块的好处。如果只有保存测试需要存根,为什么不将代码保留在测试中,而不是将其移动到在每次测试之前运行的 before 块中?

2) 更根本的是,before 块会干扰创建测试指定的内容吗?创建测试表明 Message 应该接收带有一些参数的新消息,然后使用 post :create 对其进行测试。但是,如果 before 块只是取消对 new 的调用,那不是短路了创建测试中的 should_receive 断言吗?也许我不了解 stub 和 should_receive 是如何交互的。

【问题讨论】:

    标签: rspec functional-testing stub


    【解决方案1】:

    如果只有保存测试需要存根

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

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

    所以是的,Message.new 需要为每个示例存根。

    如果 before 块只是将调用 new 存根,那不是在创建测试中短路了 should_receive 断言吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-09
      • 1970-01-01
      • 2014-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多