次のようなコードがあるとします。
class Car
def test_drive!; end
end
class AssemblyLine
def produce!
car = Car.new
car.test_drive!
end
end
今、RSpec を使用して、私はテスト/スペックAssemblyLine
も実行せずに行いたいと考えてCar
います。Ruby では依存性注入を行わないと聞きましたが、new
代わりにスタブを使用しています。
describe AssemblyLine
before do
Car.stub(:new).and_return(double('Car'))
end
describe '#produce'
it 'test-drives new cars' do
the_new_instance_of_car.should_receive(:test_drive) # ???
AssemblyLine.new.produce!
end
end
end
ご覧のとおり、問題は にありthe_new_instance_of_car
ます。produce
が呼び出される前はまだ存在せず、produce
返された後では、メソッド呼び出しの期待値を設定するには遅すぎます。
スタブ化されたメソッドでコールバックを使用する回避策を考えることができますが、new
それはかなり厄介です。この一見一般的な問題を解決するには、よりエレガントで慣用的な方法が必要です。右...?
更新:これが私がそれを解決した方法です。
describe AssemblyLine
def stub_new_car(&block)
Car.stub(:new) do
car = double('Car')
block.call(car) if block
car
end
end
before { stub_new_car } # to make other tests use the stub as well
describe '#produce'
it 'test-drives new cars' do
stub_new_car { |car| car.should_receive(:test_drive) }
AssemblyLine.new.produce!
end
end
end