2012-06-17 14 views
1

说我有这样的代码:如何期待一个新创建的测试双方的方法调用?

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 

回答

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 
+0

啊,我简化得太多了。第一个不起作用,因为涉及多个“Car”。第二种方法确实有效,但也是练习Car类,这正是我想要避免的。 – Thomas

+0

好吧,其实你确实把我放在了正确的轨道上。我可以用一种不同的方式来存储'new',覆盖通用的'''''''在特定的测试中''test'drive!'被调用。谢谢!需要莫阿咖啡... – Thomas

相关问题