如何在规范中创建类而不污染全局名称空间?

问题描述 投票:0回答:1

在规范的上下文中定义类并且不污染全局名称空间的最佳方法是什么?另一个文件如何访问该常量?

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具有更新的自述文件

ruby-on-rails ruby testing rspec
1个回答
0
投票

嗯,让我们看看:

正在运行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
© www.soinside.com 2019 - 2024. All rights reserved.