如何使用rspec在构造函数中测试方法调用

时间:2011-03-11 08:54:26

标签: ruby constructor mocking rspec

我有一个这样的构造函数:

class Foo
  def initialize(options)
    @options = options
    initialize_some_other_stuff
  end
end

并且想要测试对initialize_some_other_stuff的调用,如果实例化一个新的Foo对象。

我发现了这个问题rspec: How to stub an instance method called by constructor?,但调用Foo.any_instance(:initialize_some_other_stuff)的建议解决方案在我的rspec版本(2.5.0)中不起作用。

有人可以帮我测试这个构造函数调用吗?

3 个答案:

答案 0 :(得分:0)

在您的规范中,您可以拥有以下内容:

class Foo
  attr_reader :initializer_called
  def initialize_some_other_stuff
    @initializer_called = true
  end
end

foo = Foo.new
foo.initializer_called.should == true

如果构造函数调用initiaize_some_other_stuff方法,则foo.initializer_called应该为真。

答案 1 :(得分:0)

你走了:

stub_model(富).should_receive(:some_method_call)。随着(optional_argument)

答案 2 :(得分:0)

由于initialize_some_other_stuff方法是该类的私有方法,因此您不必关心它是否执行。也就是说,如果该方法执行了一些不希望您的测试等待的昂贵操作,那么模拟该操作就可以了。

所以,如果Foo看起来像这样:

class Foo
  attr_reader :options, :other_stuff

  def initialize(options)
    @options = options
    initialize_some_other_stuff
  end

  def initialize_some_other_stuff
    @other_stuff = Bar.new.long_running_operation
  end
end

然后您可以像这样模拟对Bar#long_running_operation的呼叫:

describe Foo do
  subject(:foo) { described_class.new(options) }

  let(:options) { 'options' }
  let(:bar) { instance_double(Bar, long_running_operation: 42) }

  before do
    allow(Bar).to receive(:new).and_return(bar)

    foo
  end

  it 'initializes options' do
    expect(foo.options).to eq(options)
  end

  it 'initializes other stuff' do
    expect(foo.other_stuff).to eq(bar.long_running_operation)
  end
end

现在,您正在测试作业。但是,您不必等待昂贵的操作完成。