我想写这样的东西:
it 'does not invoke any MyService' do
MyService.should_not_receive(<any method>)
tested_method
end
我不想明确列出 MyService 的所有方法,因为这会导致脆弱的测试,如果将新方法添加到 MyService 中,可能会默默地给出误报。
我想写这样的东西:
it 'does not invoke any MyService' do
MyService.should_not_receive(<any method>)
tested_method
end
我不想明确列出 MyService 的所有方法,因为这会导致脆弱的测试,如果将新方法添加到 MyService 中,可能会默默地给出误报。
用双精度替换实现怎么样?
it 'does not invoke any MyService' do
original_my_service = MyService
begin
# Replace MyService with a double.
MyService = double "should not receive any message"
tested_method
ensure
# Restore MyService to original implementation.
MyService = original_my_service
end
end
如果调用 MyService 中的方法,它应该引发:
RSpec::Mocks::MockExpectationError: Double "should not receive any message" received unexpected message :some_method with (no args)
如果将MyService
依赖项注入到对象中,则可以将其替换为没有定义方法的模拟,这样任何方法调用都会引发异常。
让我给你看一个例子:
class Manager
attr_reader :service
def initialize(service = MyService)
@service = service
end
def do_stuff
service.do_stuff
end
def tested_method
other_stuff
end
end
测试将是:
context "#do_stuff" do
let(:manager) { Manager.new }
it 'invokes MyService by default' do
MyService.should_receive(:do_stuff)
manager.do_stuff
end
end
context "#tested_method" do
let(:service) { mock("FakeService") }
let(:manager) { Manager.new(service) }
it 'does not invoke any service' do
expect { manager.tested_method }.not_to raise_error
end
end
it 'does not invoke MyService' do
stub_const('MyService', double)
tested_method
end
任何访问尝试都MyService
将返回模拟的 RSpec double
。由于双打在收到未显式存根的消息(并且没有被存根)时会引发错误,因此任何调用MyService
都会引发错误。
https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/basics/test-doubles