2013-08-21 71 views
18

如何僅在第一次調用時存根方法,在第二次調用時它應該按預期行爲?僅在第一次調用Rspec時使用存根方法

我有以下方法:

def method 
    do_stuff 
rescue => MyException 
    sleep rand 
    retry 
end 

我想要的do_stuff第一個呼叫,以提高MyException,但在第二個電話,可以正常工作。我需要做到這一點,以測試我的rescue塊而不會發生無限循環。

有沒有辦法做到這一點?

回答

15

您可以將塊傳遞給將在調用存根時調用的存根。然後,您可以在那裏執行未讀短文,除了做任何你需要的。

class Foo 
    def initialize 
    @calls = 0 
    end 

    def be_persistent 
    begin 
     increment 
    rescue 
     retry 
    end 
    end 

    def increment 
    @calls += 1 
    end 
end 

describe "Stub once" do 
    let(:f) { Foo.new } 
    before { 
    f.stub(:increment) { f.unstub(:increment); raise "boom" } 
    } 

    it "should only stub once" do 
    f.be_persistent.should == 1 
    end 
end 

似乎在這裏很好地工作。

$ rspec stub.rb -f doc 

Stub once 
    should only stub once 

Finished in 0.00058 seconds 
1 example, 0 failures 

或者,你可以只跟蹤呼叫的數量和基於呼叫次數存根返回不同的結果:

describe "Stub once" do 
    let(:f) { Foo.new } 

    it "should return different things when re-called" do 
    call_count = 0 
    f.should_receive(:increment).twice { 
     if (call_count += 1) == 1 
     raise "boom" 
     else 
     "success!" 
     end 
    } 

    f.be_persistent.should == "success!" 
    end 
end 
+0

這解決了我跑進用ActiveRecord的只讀功能的一個問題 - 我有一個標記爲readonly('def readonly; true; end')的模型,但需要在測試中創建實例,並且不想用生產代碼複用測試代碼。解決方案(在factory_girl工廠中):'after(:build)do | f | f.stub(:只讀?){f.unstub(:只讀?);假}; f.save !; end' –

相關問題