2012-11-02 48 views
0

的代码样本下面显示从RSpec的书控制器规格的篇章重构:存根,Should_Receive,并在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 

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块?

2)更基本的是,前面的块是否会干扰创建测试指定的内容?创建测试表示,消息应该接收新的参数,然后使用post:create进行测试。但是,如果前面的块只是将调用刷新到新的,那么不会在创建测试中将should_receive断言短路吗?也许我不了解stub和should_receive如何相互作用。

回答

0

如果只保存测试需要存根

一个典型的创建行动看起来像这样:

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

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

如果before块只是将新的调用存根删除,那么创建测试中的should_receive断言是不是短路?

实际上它的工作原理是相反的。前面的程序块先运行,然后剔除:new,然后运行消息期望并替换存根。您可以删除before块并将存根放在其他两个示例的开头,并获得相同的效果。

相关问题