2014-07-19 20 views
1

我有一個具有以下簽名的方法RSpec的參數匹配,包括一個可選的參數

def my_method(first, second = {}) 

因此,它可以以兩種方式調用的方法...

my_method 'first' 
my_method 'first', { second: 'value' } 

我只對我的測試中測試第一個參數的值感興趣,因此我試圖提出一個RSpec匹配器語句來完成這項工作。我有壁櫥裏

expect_any_instance_of(my_clazz).to receive(:my_method).with(code, anything).once 

但是,當我不在第二個參數傳遞,出現以下錯誤

 expected: ('first', anything) 
      got: ('first') 

我知道你可以通過不同的匹配到阿森納的失敗with方法我找不到任何能夠以這種方式執行可選任務的任何東西。

任何人都可以提供有關如何實現這一目標的見解嗎?

+2

rspec跟蹤器上的這個[issue](https://github.com/rspec/rspec-mocks/issues/707)意味着目前沒有特別簡單的方法來執行此操作 –

+0

從這個問題看起來像你的權利。可能不得不觀察並等待這些問題得到解決。感謝您的鏈接 –

回答

0

簡單的解決方案:

expect(my_instance).to receive(:my_method) do |first_param,other_param| 
    expect(first_param).to eq(code) 
end 

這將使你在這兩種情況下的匹配。

+0

這不適合我。我正在使用Sinatra,並且我正在將應用程序傳遞給'first_param',而實際值正在傳遞給'other_param'。如果我解決了這個問題,使用這種風格似乎與代碼的執行範圍混亂,因爲這會導致拋出錯誤。 –

+0

發現了與此相關的另一個RSpec問題,但並沒有真正的工作解決方案(我可以工作)https://github.com/rspec/rspec-mocks/issues/377 –

+0

這很奇怪,我使用這種風格匹配很多,從來沒有看到它導致其他副作用。你確定匹配器在這裏引起問題嗎? –

0

試試這個:但是

example do 
    klass = Class.new 

    expect_any_instance_of(klass).to receive(:my_method).at_least(:once) do |instance, arg_1, *| 
    expect(arg_1).to eq('first') 
    end 

    instance = klass.new 
    instance.my_method('first') 
    instance.my_method('first', second: 'value') 
end 

注意的是,我們建議any_instance功能無法使用:https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/working-with-legacy-code/any-instance

+0

無效,與以前相同。我剛剛意識到我正在使用'expect_any_instance_of',而不是這樣做。更新我的問題 –

+0

仍然中斷。有些使用塊的做法確實會在之後直接打破測試。猜猜我將不得不等待改進的語法 –

+0

好吧,我終於搞清楚發生了什麼事情。在這裏添加一個塊是替換my_method的實現,以便它永遠不會返回期望的值。在我的情況下,'my_method'是一個幫助器,它填充響應體,而不是JSON,它只是返回'true'作爲'expect'調用的結果。因此,爲什麼我的測試打破了Rack作爲錯誤類型拋出了這個機構。任何想法爲什麼會這樣做? –

0

則避短的響應,你應該加上 'and_call_original' 的方法:

expect(my_instance).to receive(:my_method) do |first_param,other_param| 
    expect(first_param).to eq(code) 
end.and_call_original