如何将带有存根方法的对象在 it_behaves_like 中传递给 rspec 中的 shared_examples_for 块? [英] How to pass objects with stubbed methods in it_behaves_like to shared_examples_for block in rspec?
问题描述
我有一个规范
describe MyClass do
it_behaves_like SharedClass, MyClass.new
end
在我的共享示例规范中,我有
and in my shared example spec, I have
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 语句之前存根它们.喜欢,
There are few methods in MyClass instance that I cannot stub in the shared_examples_for block, so I want to stub them before passing it in it_behaves_like statement. like,
describe MyClass do
before do
@instance = MyClass.new
@instance.stub(:my_class_method)
end
it_behaves_like SharedClass, @instance
end
但我不能那样做.它让我很失望
无方法错误:未定义的方法 `some_my_class_method=' for nil:NilClass
but I cannot do that.It throws me
NoMethodError:
undefined method `some_my_class_method=' for nil:NilClass
不知何故,我无法在 shared_examples_for 上下文中访问该 @instance 对象.我正在使用 ruby 1.9.3p392 和 rspec (2.14.1)
somehow I am not able to access that @instance object in the shared_examples_for context. I am using ruby 1.9.3p392 and rspec (2.14.1)
推荐答案
问题是您传递给 it_behaves_like
的参数在调用 it_behaves_like
时被评估,而 before
块在共享示例执行之前被评估,这发生在稍后的时间.结果,作为参数的 @instance
被评估为 nil
并且形参 instance
被赋值为 nil
,导致您的 undefined method
错误.
The problem is that the arguments you pass to it_behaves_like
are evaluated at the time it_behaves_like
is called, while the before
block is evaluated just before the shared example is executed, which occurs at a later time. As a result, @instance
as an argument is evaluated to nil
and the formal parameter instance
is assigned nil
, resulting in your undefined method
error.
我不知道有什么简单的方法可以完成您想要完成的任务.这个文档是为了消除形参,并要求调用者传递一个使用let
来建立参数值的块,使用一些约定好的变量,如下:
I don't know of any easy way to do what you're trying to accomplish. One alternative shown in this documentation is to eliminate the formal parameter and require the caller to pass a block which uses let
to establish the argument value, using some agreed to variable, as follows:
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
在调用时设置.
In addition to being more verbose, however, this has the disadvantage that there is no implicit documentation within your shared example that it expects instance
to set when it's called.
虽然我没有在任何地方看到它讨论过,但是当且仅当形参的值为 nil代码>,为方便起见可以默认.不幸的是,您不能对两者使用相同的变量,因为参数的值将始终优先.
Although I've not seen it discussed anywhere, a somewhat hacky alternative would be have your shared example use the agreed-to-variable from the block if and only if the value of the formal parameter is nil
, which could be defaulted for convenience. Unfortunately, you can't use the same variable for both, as the value of the parameter will always take precedence.
这篇关于如何将带有存根方法的对象在 it_behaves_like 中传递给 rspec 中的 shared_examples_for 块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!