RSpec模拟对象上的所有方法

RSpec模拟对象上的所有方法,rspec,mocking,Rspec,Mocking,我现在正在做一些rspec测试,其中一个初始化参数是“外来”类,这意味着我不知道它来自哪里。它是从我正在使用的框架中注入的。在我的代码中,我需要将这个对象用于各种事情,主要/专门地调用方法将数据传递给这个对象(无数据提取) 是否可以完全模拟对象,以便验证是否调用了某些未定义的方法 #an example of what this object could look like let(:my_obscure_object) { RSpec.complete_mock } #NOTE: This d

我现在正在做一些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
我现在能想到的解决这个问题的方法是创建一个对象并存根我可能需要的每一个可能的方法,就像这样

#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

我的问题有什么解决方案吗?

您可以创建一个test double,它将使用
作为\u null\u 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\u message\u chain
方法仅从RSpec 3.0.0.beta2开始提供,并且不允许您指定任何预期的参数值。如果要使用旧版本的RSpec或指定传递的参数,可以使用单个测试双精度重写该期望。

类是否“模糊”?正在努力找到double方法的字符串输入的含义。否。
double
的第一个参数只是一个句柄,可用于调试目的。从RSpec功能的角度来看,它被忽略了。只是在文档中找到了它。字符串只是一个标识符。工作完美:)谢谢!