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

发布于 2024-10-21 13:40:12 字数 506 浏览 3 评论 0原文

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

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

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

我发现这个问题rspec:如何存根实例方法由构造函数调用? 但建议的调用 Foo.any_instance(:initialize_some_other_stuff) 的解决方案在我的 rspec 版本 (2.5.0) 中不起作用。

谁能帮我测试这个构造函数调用?

i have a constructor like this:

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

and want to test the call to initialize_some_other_stuff if a instantiate a new Foo object.

I found this question rspec: How to stub an instance method called by constructor? but the suggested solution to call Foo.any_instance(:initialize_some_other_stuff) does not work in my rspec version (2.5.0).

Can anyone help me to test this constructor call?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寄离 2024-10-28 13:40:12

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

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_known 应该为 true。

In you spec, you could have the following:

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

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

If the constructor calls the initiaize_some_other_stuff method, foo.initializer_called should be true.

A君 2024-10-28 13:40:12

在这里:

stub_model(Foo).should_receive(:some_method_call).with(optional_argument)

Here you go:

stub_model(Foo).should_receive(:some_method_call).with(optional_argument)

挥剑断情 2024-10-28 13:40:12

由于 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

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

Since the initialize_some_other_stuff method is private to the class, you should not care if it executes or not. That said, if that method performs some expensive operation that you don't want your test waiting for, then it is quite okay to mock that operation.

So, if Foo looked like this:

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

Then you could mock out the call to Bar#long_running_operation like this:

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

Now, you're testing the assignments. But, you're not waiting on the expensive operation to complete.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文