Rspec / Rails:如何验证没有调用类的方法

时间:2013-06-25 06:51:05

标签: ruby-on-rails rspec

我想写这样的东西:

it 'does not invoke any MyService' do
    MyService.should_not_receive(<any method>)
    tested_method
end

我不想明确列出MyService的所有方法,因为这会导致一个脆弱的测试,如果将新方法添加到MyService,可能会无声地给出误报。

3 个答案:

答案 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