私は質問をうまく表現できない場合は、正しいものを入力してください。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
しかし、(もちろんありません、実際にすべてが、どれも例すべてを列挙/真/偽の組み合わせのための1つ/いくつか/多くの)私は実際にはユニットの方法をテストして感じていませんの統合私は私のgood
メソッドに "リーク"の動作の知識のチンのselect
テストケースの数を掛ける原因となります。ある意味で私のテストケースは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
-statementを移動するだけで必要性を移動させているという事実を考慮してくださいselect
を使用することを避けるために、とても些細に見えるかもしれません別の場所へのテストのために。
私はここで何か基本的なことを誤解しているか見落としていますか?
Ps 1.簡潔さのためにいくつかのテストケースを無視しています。
Psの2.私はユニットない統合の必要性を強調していた理由のショートバージョンがテストはこのビデオである:https://www.youtube.com/watch?v=VDfX44fZoMc
編集: この質問フレーズに良い方法はおそらくだろう:最初のテストは、古典主義者がどのようにしてFilters.good
をテストするかの要点の例ですが、モチストはどのようにテストしますか?
ソリューションを見つけましたか? –
@PaulFioravanti提供していただきありがとうございます。しかし、私にはまだ解決策がないようです。私は質問に明確化を加えています。 – chris