使用shared_examples_for将模块混合到rspec上下文中

时间:2013-11-13 07:48:28

标签: rspec ruby-2.0

我使用shared_examples_for

在rspec中包含了来自模块的常量
shared_examples_for 'Constants' do
  include AllTestData.UserConstants
end
# for example I have AllTestData.UserConstants::USER_NAME = 'John Dorian'

describe Users do
  include_context 'Constants'
  p USER_NAME   
end

当我以前使用ruby 1.9.2时它起作用了。 现在我使用ruby 2.0.0。现在它是引发错误 - NameError:未初始化的常量USER_NAME

为什么现在它失败了,我怎么能解决它?谢谢

1 个答案:

答案 0 :(得分:3)

这与常量查找规则如何变化有关。对于某些历史记录,请参阅Making Sense of Constant Lookup in Ruby by John Firebaugh。您会注意到,在1.8中,当一个对象的实例是instance_eval时,常量查找是在词法上进行的。这在1.9中有所改变。事实上,1.9,有几次迭代,并且class_eval常量查找在版本之间不一致。

似乎在Ruby 2.0中,常量查找的规则又回到了1.8的方式。所以现在,RSpec严重依赖的instance_exec可以追溯到词法常量规则,而不会搜索层次结构。

您可以看到这一点:

class Foo
  X = "Does it work?"
end

f = Foo.new
f.instance_exec do
  p X
end

在Ruby 1.9.2中,输出:`“它有效吗?”

在Ruby 2.0.0中,输出:NameError: uninitialized constant X

您可以使用self.class::CONSTANT

委托给班级来解决这个问题
module Bar
  B = "A bit wonky"
end

example_group = Class.new do
  include Bar
end

example = example_group.new

example.instance_exec do
  p self.class::B
end
# => "A bit wonky"