【问题标题】:Using shared_examples_for for mix a module into an rspec context使用 shared_examples_for 将模块混合到 rspec 上下文中
【发布时间】:2023-03-17 19:40:01
【问题描述】:

我使用 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: uninitialized constant USER_NAME

为什么现在它失败了,我该如何解决?谢谢

【问题讨论】:

  • 包括:AllTestData::UserConstants

标签: rspec ruby-2.0


【解决方案1】:

这与常量查找规则的变化有关。有关一些历史记录,请参阅Making Sense of Constant Lookup in Ruby by John Firebaugh。您会注意到,在 1.8 中,当对象的实例为 instance_eval'd 时,常量查找是按词法执行的。这在 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 中,这会输出:`"Does it work?"

在 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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多