2013-08-21 37 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' –

相关问题