2015-06-20 40 views
2

採用摩卡嘲笑或存根遠跨網絡進入一個功能非常有用:如何在單元測試中用其他方法臨時替換方法?

def test_something 
    NetworkClass.stub(:fetch_something, "contrived example") 

    assert_equal "contrived example", NetworkClass.fetch_something 
end 

但更多的時候,我的網絡交叉功能需要一定的投入,以及輸入影響是什麼函數返回。對於我的單元測試,我只準備了一個Hash,其中包含我的測試套件需要運行的輸入和輸出。問題是,現在我不能再使用Mochas .stub.expects,因爲它們不允許我替換實際執行某些操作的函數。

目前我在做這樣的事情:

def setup 
    @subject = NetworkClass.new 

    test_data = fetch_test_data 

    @subject.define_singleton_method(:fetch_something) { |input| 
    test_data[input] or fail "Unexpected stub input: #{input}" 
    } 
end 

但這永久改變的主題,所以我不能使用此方法樁模塊函數或類方法。

有沒有辦法用另一種方法「臨時」替換方法,就像摩卡的.stub一樣簡單?

如果有人想告訴我,這是一個不好的方式來測試並告訴我一個更好的方法,我想我也會接受這個答案。這一直在困擾我一段時間。爲了避免這種


一個顯而易見的方法是存根在考慮特定輸入每個測試功能的方法,但是在我看來,像很多額外的「樣板」的測試代碼沒有實際的好處。另外,通過這種方式,我可以確定,我不會忘記在某處存儲方法,並且每次運行我的測試套件時都會意外地通過網絡。

+0

我想答案是聲明另一個類相同的接口。至少我是這麼做的。 – Casey

回答

1

就像你說的,如果你知道測試中的輸入是什麼,你可能仍然可以使用摩卡的功能。

NetworkClass.stub(:fetch_something).with(input).returns(test_data[input])

這僅fetch_something時調用正確的輸入將被執行。您可以通過不同的輸入以這種方式創建幾個存根。

一般來說,這應該不成問題,因爲您的測試應該是可預測和可重複的。這意味着每個獨立的測試用例應該運行相同的代碼路徑,並因此爲您的NetworkClass觸發相同的參數。每個測試用例都應該運行一個代碼路徑並儘可能地集中。

編輯

不知道你的測試框架是什麼,但應該有每個測試用例之前安裝和拆卸機制。這樣你可以使用你的方法,並在每個測試用例之後恢復類。

-1

在RSpec的3你可以使用allow

allow(NetworkClass).to receive(:fetch_something).with(input) { test_data[input] } 

或(更多的顆粒測試)

allow(NetworkClass).to receive(:fetch_something) do |arg| 
    expect(arg).to eql test_data[input] 
end 
相關問題