如果我對這個問題的措辭不佳,請糾正我。在rspec單元測試中嘲笑選擇與期望
假設下面的代碼:
class Filters
def self.good ducks
ducks.select(&:good?)
end
end
當然,可以測試這樣的方法:
describe Filters, '#good' do
let(:good) { double(:good, good?: true) }
let(:bad) { double(:bad, good?: false) }
subject { Filters.good(ducks) }
context 'none' do
let(:ducks) { [] }
it { is_expected.to eq [] }
end
context 'one good' do
let(:ducks) { [good] }
it { is_expected.to eq [good] }
end
context 'one bad' do
let(:ducks) { [bad] }
it { is_expected.to eq [] }
end
context 'one good and one bad' do
let(:ducks) { [good, bad] }
it { is_expected.to eq [good] }
end
context 'some good and some bad' do
let(:ducks) { [good, bad, bad, good, bad, good] }
it { is_expected.to eq [good, good, good] }
end
end
但枚舉所有的情況下(當然不是真正所有,但無/一個/一些/許多組合的真/假good
狀態)讓我覺得我其實不是單元測試方法,但集成測試它,因爲我讓將知識select
的行爲知識泄露到我的good
方法中,導致測試用例的數量增加。從某種意義上說,我的測試用例正在測試select
方法的行爲。
對我來說,似乎更適合於使用模擬和檢查(如在檢查而不是測試),該方法委託正確。如果人們正在整合自己編寫的功能,就可以做到這一點。類似於我們的例子可以說expect(obj).to receive(:foo).with(:bar)
。
下面的示例不起作用,但我相信它表達了我想要做的事情,而不是枚舉所有情況。
describe Filters, '#good' do
it 'returns only good ones' do
ducks = double(:ducks)
expect(ducks).to receive(:filter).with(:good?).and_return(:filtered)
expect(Filters.good(ducks).to eq)
end
end
的例子可能看起來瑣碎因此要避免爭論說,這是一個無用的方法和的Filter.good
用戶只需應該使用select
,請考慮的是,移動select
語句來僅移動需要測試到另一個位置。
我是否誤解或忽略了一些根本性的東西?
ps 1.爲了簡潔起見,我忽略了一些測試用例。
詩篇2.我強調需要單元而不是整合的原因所在短版測試視頻:https://www.youtube.com/watch?v=VDfX44fZoMc
編輯: 措辭提供更好的方法這個問題便叫是:第一個測試是一個如何測試古典主義者Filters.good
的一個例子,但是測試者將如何測試?
您是否找到解決方案? –
@PaulFioravanti謝謝你提供的答案。但在我看來,目前還沒有解決方案。我在這個問題上加了一個說明。 – chris