RSpec模拟对象上的所有方法

时间:2014-02-19 12:35:10

标签: rspec mocking

我正在进行一些rspec测试,其中一个初始化参数是一个“外来”类,这意味着我不知道它来自哪里。它是从我正在使用的框架中注入的。在我的代码中,我需要利用这个对象来做各种事情,主要是/专门调用方法将数据传递给这个对象(没有数据提取)。

是否可以完全模拟对象,以便我可以验证是否调用了某些未定义的方法。

#an example of what this object could look like
let(:my_obscure_object) { RSpec.complete_mock } #NOTE: This does not work
...
it "verify .whatever method is called" do
  expect(my_obscure_object).to receive(:whatever).with(some_data)
  my_class.work
end

it "verify .sub_whatever method is called" do
  expect(my_obscure_object.sub_thing).to receive(:sub_whatever).with(some_data)
  my_class.work2
end

我现在想到的解决这个问题的方法是创建一个对象和stub我可能需要的每一种可能的方法,比如这个

#an example of a tedious method to solve my problem
let(:my_obscure_object) { Object.new }
before(:each) do
  my_obscure_object.stub(:whatever) { nil }
  my_obscure_object.stub(:whatever2) { nil }
  my_obscure_object.stub(:whatever3) { nil }
  my_obscure_object.stub(:whatever4) { nil }
  my_obscure_object.stub(:whatever5) { nil }
  ob = Object.new
  ob.stub(:sub_whatever) { nil }
  my_obscure_object.stub(:sub_thing) { ob }
end
...
it "verify .whatever method is called" do
  expect(my_obscure_object).to receive(:whatever).with(some_data)
  my_class.work
end
it "verify .sub_whatever method is called" do
  expect(my_obscure_object.sub_thing).to receive(:sub_whatever).with(some_data)
  my_class.work2
end

我的问题有解决办法吗?

1 个答案:

答案 0 :(得分:2)

您可以使用as_null_object创建一个接受所有方法调用的测试双,如下所示:

describe "SO example" do
  #an example of what this object could look like
  let(:my_obscure_object) { double("obscure").as_null_object }
  let(:some_data) { 'foobar'}

  it "verify .whatever method is called" do
    expect(my_obscure_object).to receive(:whatever).with(some_data)
    my_obscure_object.whatever(some_data)
  end

  it "verify .sub_whatever method is called" do
    expect(my_obscure_object).to receive_message_chain(:whatever, :sub_whatever)
    my_obscure_object.whatever.sub_whatever
  end

end

请注意,receive_message_chain方法仅适用于github提供的RSpec 3.0.0.beta2,并且不允许您指定任何预期的参数值。如果要使用旧版本的RSpec或指定传递的参数,可以使用单个测试双精度重写该期望。