如何在不污染全局命名空间的情况下在规范中创建 类?
How to create classes in specs without polluting global namespace?
在规范上下文中定义 class 并且不污染全局命名空间的最佳方法是什么?其他文件如何访问该常量?
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
规格 - 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
如果您 运行 定义虚拟对象的规范 class
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"
检查链上的第一个对象
Object::METRICS_NAMESPACE
=>"ExtendedClass.Metrics.namespace"
更进一步
Class::METRICS_NAMESPACE
(pry):2: warning: toplevel constant METRICS_NAMESPACE referenced by Class::METRICS_NAMESPACE
=> "ExtendedClass.Metrics.namespace"
TL; DR
如您所说,当您执行 METRICS_NAMESPACE = "ExtendedClass.Metrics.namespace"
时,您创建了一个全局命名空间常量。 (也就是最上面的ruby里面的一个常量,Class)
只需这样做即可
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
在规范上下文中定义 class 并且不污染全局命名空间的最佳方法是什么?其他文件如何访问该常量?
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
规格 - 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
如果您 运行 定义虚拟对象的规范 class
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"
检查链上的第一个对象
Object::METRICS_NAMESPACE
=>"ExtendedClass.Metrics.namespace"
更进一步
Class::METRICS_NAMESPACE
(pry):2: warning: toplevel constant METRICS_NAMESPACE referenced by Class::METRICS_NAMESPACE
=> "ExtendedClass.Metrics.namespace"
TL; DR
如您所说,当您执行 METRICS_NAMESPACE = "ExtendedClass.Metrics.namespace"
时,您创建了一个全局命名空间常量。 (也就是最上面的ruby里面的一个常量,Class)
只需这样做即可
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