说我有这样的代码:
class Car
def test_drive!; end
end
class AssemblyLine
def produce!
car = Car.new
car.test_drive!
end
end
现在,使用RSpec我想测试/ spec 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
答案 0 :(得分:1)
您可以在测试双倍上设置期望值:
describe AssemblyLine do
let(:car) { double('Car') }
before { Car.stub(:new) { car } }
describe "#produce" do
it "test-drives new cars" do
car.should_receive(:test_drive!)
AssemblyLine.new.produce!
end
end
end
您也可以在课堂上致电any_instance
(我认为从RSpec 2.7开始):
describe AssemblyLine do
describe "#produce" do
it "test-drives new cars" do
Car.any_instance.should_receive(:test_drive!)
AssemblyLine.new.produce!
end
end
end