我有一个类似
的规范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
但是我不能这样做。它会把我扔掉
NoMethodError:
未定义的方法`some_my_class_method ='为nil:NilClass
不知怎的,我无法在shared_examples_for上下文中访问该@instance对象。 我使用的是ruby 1.9.3p392和rspec(2.14.1)
答案 0 :(得分:2)
问题是传递给it_behaves_like
的参数是在调用it_behaves_like
时计算的,而before
块是在执行共享示例之前计算的,这会发生晚些时候。因此,@instance
作为参数评估为nil
,形式参数instance
被指定为nil
,从而导致undefined method
错误。
我不知道有什么简单的方法来做你想要完成的事情。 this documentation中显示的一个替代方法是消除形式参数并要求调用者传递一个块,该块使用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
时,你的共享示例才会使用块中的约定变量。这可能是为了方便而违约的。不幸的是,你不能为两者使用相同的变量,因为参数的值总是优先。