如何传递带有存根方法的对象\u行为\u类似于rspec中块的共享\u示例\u?

如何传递带有存根方法的对象\u行为\u类似于rspec中块的共享\u示例\u?,rspec,Rspec,我有一个像 describe MyClass do it_behaves_like SharedClass, MyClass.new end 在我的共享示例规范中,我有 shared_examples_for SharedClass do |instance| before do instance.some_my_class_method = double end # some specs here end MyClass实例中有几个方法无法存根到shared_ex

我有一个像

describe MyClass do
  it_behaves_like SharedClass, MyClass.new
end
在我的共享示例规范中,我有

shared_examples_for SharedClass do |instance|
  before do 
    instance.some_my_class_method = double
  end
  # some specs here
end
MyClass实例中有几个方法无法存根到shared_examples_for块中,因此我希望在将其传递到it_behaves_like语句之前存根它们。像

describe MyClass do
  before do
    @instance = MyClass.new
    @instance.stub(:my_class_method)
  end
  it_behaves_like SharedClass, @instance
end
但我做不到。这让我感到困惑
命名错误: nil:NilClass的未定义方法'some\u my\u class\u method='

不知何故,我无法在共享的上下文中访问@instance对象。
我使用的是ruby 1.9.3p392和rspec(2.14.1)

问题是,传递给
it\u behaves\u like
的参数是在调用
it\u behaves\u like
时计算的,而
before
块是在执行共享示例之前计算的,这会在以后发生。结果,
@instance
作为参数被计算为
nil
,并且形式参数
instance
被赋值为
nil
,从而导致
未定义的方法出现错误

我不知道有什么简单的方法可以实现你想要实现的目标。中显示的一种替代方法是消除形式参数,并要求调用方传递一个块,该块使用
let
来建立参数值,使用一些约定的变量,如下所示:

describe MyClass do
  it_behaves_like SharedClass {let(:instance) { MyClass.new }}
end

describe MyClass do
  it_behaves_like SharedClass do
    let(:instance) do
      myClass = MyClass.new
      myClass.stub(:my_class_method)
      myClass
    end
  end
end
但是,除了更加冗长之外,这还有一个缺点,即在调用时,共享示例中没有它期望
instance
设置的隐式文档

尽管我没有看到在任何地方讨论过它,但有一个比较粗糙的替代方法是,如果且仅当形式参数的值为
nil
,为方便起见,可以默认使用块中的agreed to变量。不幸的是,不能对两者使用相同的变量,因为参数的值将始终优先。

由于
let(:instance)
实际上定义了一个方法,因此实际上可以对let使用与
共享示例\u for
参数(裸字)相同的名称。只需调用
instance()
而不是简单的
instance
,它就会知道您引用的是方法,而不是局部变量。。。