【发布时间】:2020-11-26 14:24:06
【问题描述】:
我在 RSpec 测试中基本上有这个设置:
RSpec.describe Something do
describe '#something' do
let(:my_var) { 'some data' }
let(:my_object) { MyObject.new }
it 'example' do
my_object.instance_eval { @my_inst_var = my_var } # ERROR here
end
end
end
这会导致
NameError: #MyObject:0x5d14e99e 的未定义局部变量或方法“myvar”
我了解,在my_object 的执行上下文中,Ruby 不知道如何处理 RSpec 中 let 构造的“魔法”。我知道我可以在这里使用“普通变量”而不是 let,我也可以这样做(这就是我目前解决问题的方式):
# This works of course
it 'example' do
mv = my_var # Forces the let(:my_var) to be evaluated
my_object.instance_eval { @my_inst_var = mv }
end
问题:假设我确实想在示例中使用let 和`instance_eval,有没有更好的方法?
【问题讨论】:
-
"我知道,在 my_object 的执行上下文中,Ruby 不知道如何处理 RSpec 中 let 构造的“魔法”。" ——没有魔法。
let(:foo)只是定义了一个名为foo的方法,仅此而已。instance_eval的全部意义 是更改self以便在其他地方查找方法,所以很明显,foo不存在。这就是为什么即使是过去大量使用它的社区(例如 Rails)也几乎禁止使用它的许多原因之一:因为那些看起来应该是在范围内,不是。