2016-09-29 54 views
1

假设我们有一个具有从另一个 存根依赖对象

class Ship 
    def initialize 
    ... 
    end 

    def launch 
    ShipLauncher.new(self, platform: platform) 
    end 
end 


class ShipLauncher 
    def initialize(ship, platform:) 
    ... 
    end 
end 

垂直依赖的对象,我们要对它进行测试:

it do 
    allow(ShipLauncher).to receive(:new) 

    ship = Ship.new 
    ship.launch 

    expect(ShipLauncher).to have_received(:new).with(ship, platform: 'x') 
end 

到现在为止一切似乎都不错,但如果我们改变了ShipLauncher类这样

class ShipLauncher 
    def initialize(ship, platform_number:) 
    ... 
    end 
end 

测试将通过WH它不应该因为ShipLauncher类需要另一个参数。我做错了什么?我必须用集成测试来测试它吗?如果ShipLauncher类隐藏了很大的复杂性,会发生什么?我必须将所有的依赖关系存根?

回答

1

有一个功能叫"partial doubles",可以用来检查这个。

首先,您需要启用它:

RSpec.configure do |config| 
    config.mock_with :rspec do |mocks| 
    mocks.verify_partial_doubles = true 
    end 
end 

然后写你的天赋这样的:

describe Ship do 
    it "launches a ship" do 
    ship = Ship.new 
    expect(ShipLauncher).to receive(:new).with(ship, platform: 'x') 

    ship.launch 
    end 
end 

这将通过与原代码:

> rspec ship_spec.rb 
. 

Finished in 0.00429 seconds (files took 0.19664 seconds to load) 
1 example, 0 failures 

现在,进行更改:

class ShipLauncher 
    def initialize(ship, platform_number:) 
    ... 
    end 
end 

,你会得到这样的错误:

rspec ship_spec.rb 
F 

Failures: 

    1) Ship should receive new 
    Failure/Error: expect(ShipLauncher).to receive(:new).with(ship, platform: 'x') 
     Missing required keyword arguments: platform_number 
    # ./ship_spec.rb:30:in `block (2 levels) in <top (required)>' 

Finished in 0.00437 seconds (files took 0.2022 seconds to load) 
1 example, 1 failure 

注意,规范是实际调用上ShipLauncherinitialize方法,通过它可以验证:

class ShipLauncher 
    def initialize(ship, platform_number:) 
    raise Exception, "This code should not be run!" 
    end 
end 

运行规范,在这两种情况下你都会得到相同的结果。部分double只是检查参数和方法名称是否与被嘲笑的对象匹配。