2012-11-02 47 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塊並將存根放在其他兩個示例的開頭,並獲得相同的效果。

相關問題