我想写这样的东西:
it 'does not invoke any MyService' do
MyService.should_not_receive(<any method>)
tested_method
end
我不想明确列出MyService的所有方法,因为这会导致一个脆弱的测试,如果将新方法添加到MyService,可能会无声地给出误报。
答案 0 :(得分:2)
如果在对象中注入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
答案 1 :(得分:2)
如何用double替换实现?
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)
答案 2 :(得分:0)
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