在规范的上下文中定义类并且不污染全局名称空间的最佳方法是什么?另一个文件如何访问该常量?
bowling_spec.rb
require "spec_helper"
describe Bowling do
context "when validate is defined" do
let(:dummy_class) {
Class.new(described_class) do
METRICS_NAMESPACE = "ExtendedClass.Metrics.namespace"
end
}
it "does nothing" do
dummy_class
end
end
end
Spec-batting_spec.rb
require "spec_helper"
describe Batting do
context do
it "does weird thing" do
expect { self.class.const_get(:METRICS_NAMESPACE) }.to raise_error(NameError)
end
end
end
如果您运行单个规格文件
rspec spec/batting_spec.rb
.
Finished in 0.00285 seconds (files took 0.12198 seconds to load)
1 example, 0 failures
如果运行定义虚拟类的规范
rspec spec/bowling_spec.rb spec/batting_spec.rb
.F
Failures:
1) Batting does weird thing
Failure/Error: expect { self.class.const_get(:METRICS_NAMESPACE) }.to raise_error(NameError)
expected NameError but nothing was raised
# ./spec/batting_spec.rb:6:in `block (3 levels) in <top (required)>'
Finished in 0.01445 seconds (files took 0.12715 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/batting_spec.rb:5 # Batting does weird thing
重现错误:我创建了一个存储库:https://github.com/pratik60/rspec-pollution具有更新的自述文件
嗯,让我们看看:
正在运行rspec spec/batting_spec.rb spec/bowling_spec.rb
2 examples, 0 failures
正在运行rspec spec/bowling_spec.rb spec/batting_spec.rb
给出您提到的错误。
现在,到binding.pry的魔力:
describe Batting do
context do
it "does weird thing" do
require 'pry'
binding.pry
expect { self.class.const_get(:METRICS_NAMESPACE) }.to raise_error(NameError)
end
end
end
self.class.ancestors
[RSpec::ExampleGroups::Batting::Anonymous,
RSpec::ExampleGroups::Batting::Anonymous::LetDefinitions,
RSpec::ExampleGroups::Batting::Anonymous::NamedSubjectPreventSuper,
RSpec::ExampleGroups::Batting,
RSpec::ExampleGroups::Batting::LetDefinitions,
RSpec::ExampleGroups::Batting::NamedSubjectPreventSuper,
RSpec::Core::ExampleGroup,
最终触摸
RSpec::Core::ExampleGroup::METRICS_NAMESPACE
(pry):4: warning: toplevel constant METRICS_NAMESPACE referenced by RSpec::Core::ExampleGroup::METRICS_NAMESPACE
=> "ExtendedClass.Metrics.namespace"
TL; DR
您实际上已经在RSpec示例组类中定义了一个常量,而不是在您的子类中定义了一个常量。
只需执行此操作
Class.new(described_class) do
self.const_set('METRICS_NAMESPACE', "ExtendedClass.Metrics.namespace")
end
rspec spec / bowling_spec.rb spec / batting_spec.rb
Finished in 1.55 seconds (files took 0.08012 seconds to load)
2 examples, 0 failures