假设我有这样的代码:
class Car
def test_drive!; end
end
class AssemblyLine
def produce!
car = Car.new
car.test_drive!
end
end
现在,使用 RSpec 我想在AssemblyLine
不锻炼Car
的情况下进行测试/规范。我听说我们不在 Ruby 中进行依赖注入,而是使用 stub 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