2016-09-19 13 views
3

我有一個遞歸方法,我需要測試方法調用的順序,以及它們被調用的次數。我遇到的問題是,這些方法調用交替。例如..我如何測試rspec mocks的有序和x次?

it 'call methods in order' do 
    expect(@instance).to have_received(:foo).ordered 
    expect(@instance).to have_received(:bar).ordered 
    expect(@instance).to have_received(:foo).ordered 
    expect(@instance).to have_received(:bar).ordered 
    expect(@instance).to have_received(:foo).ordered 
    expect(@instance).to have_received(:bar).ordered 
end 

失敗的原因與

expected: 1 time with any arguments 
received: 3 times with any arguments 

foobar被稱爲3次是正確的,但我怎麼測試他們交流?

回答

0

像這樣的東西應該工作:

it 'call methods in order' do 
    @method_calls = [] 

    allow(@instance).to receive(:foo) do 
    @method_calls << :foo 
    end 

    allow(@instance).to receive(:bar) do 
    @method_calls << :bar 
    end 

    ... 

    expect(@method_calls).to eq([:foo, :bar, :foo, :bar, :foo, :bar])  
end 

這裏有一個最小的測試,我想這說明了這一點充分:

require "rspec" 

class MyClass 
    def bar 
    end 

    def foo 
    end 

    def foobar 
    foo 
    bar 
    foo 
    bar 
    foo 
    bar 
    end 
end 

describe "Foo" do 
    describe "#foobar" do 
    let(:instance) { MyClass.new } 

    it "alternately calls foo/bar" do 
     @method_calls = [] 

     allow(instance).to receive(:foo) do 
     @method_calls << :foo 
     end 

     allow(instance).to receive(:bar) do 
     @method_calls << :bar 
     end 

     instance.foobar 

     expect(@method_calls).to eq([:foo, :bar, :foo, :bar, :foo, :bar]) 
    end 
    end 
end 

運行此規範通過,但刪除(說)的方法之一調用foobar方法會導致此錯誤:

F 

Failures: 

    1) Foo #foobar alternately calls foo/bar 
    Failure/Error: expect(@method_calls).to eq([:foo, :bar, :foo, :bar, :foo, :bar]) 

     expected: [:foo, :bar, :foo, :bar, :foo, :bar] 
      got: [:bar, :foo, :bar, :foo, :bar] 

     (compared using ==) 

     Diff: 
     @@ -1,2 +1,2 @@ 
     -[:foo, :bar, :foo, :bar, :foo, :bar] 
     +[:bar, :foo, :bar, :foo, :bar] 
    # ./rspec_test.rb:38:in `block (3 levels) in <top (required)>' 

Finished in 0.01517 seconds (files took 0.07714 seconds to load) 
1 example, 1 failure 

Failed examples: 

rspec ./rspec_test.rb:25 # Foo #foobar alternately calls foo/bar 

Hope這就說得通了。

+0

工作完美...我有類似的東西,但是增加了一個塊到'expect'調用,而不是'allow'調用.... wonderul謝謝你! – brewster

+0

很高興工作!我在一篇關於在rspec中嘲笑相互依賴關係的文章中提出了這個想法,以防你感興趣:http://tech.degica.com/en/2015/03/06/mocking-with-interdependency-in-rspec/ –

0

您應該封裝方法的遞歸部分,存根其他部分,然後通過黑盒方法(即輸入 - >輸出)測試該方法。

+0

我不關注......你能詳細說明/展示一個例子嗎? – brewster