rspec 测试时处理环境源常量的最佳方法?

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

我有一个模型,其常数如下:

  SOURCE_QUOTA = {
    'free' => (ENV['FREE_SOURCE_QUOTA'] || '5').to_i,
    'premium' => (ENV['PREMIUM_SOURCE_QUOTA'] || '100').to_i
  }.freeze

RuboCop 建议使用“Style/MutableConstant”并且应该进行冻结。

但是,在测试过程中,我想使用稍微不同的值。现在,我实际上可以修改启动 rspec 的 bash 会话的 ENV。当然。但在代码中修改它会让生活变得更容易。例如:

  describe "a thing" do
    it "does stuff" do
      ENV['FREE_SOURCE_QUOTA'] = '2'
      DataSource::SOURCE_QUOTA["free"] = ENV['FREE_SOURCE_QUOTA'].to_i
      # test code

当常量未冻结时,上述方法有效。我认为这是因为,冻结时,模型是在 Rails 环境加载期间加载的,然后该值无法静音(它已冻结!)。

在这里做什么最好?

  • 坚持使用冻结常量并确保在 rspec 运行之前设置所需的环境?
  • 不要冻结常数并保留上述测试
  • 做其他涉及解冻/重新冻结/重新加载模型的事情?

谢谢!

ruby-on-rails ruby rspec rspec-rails
2个回答
2
投票

我会考虑使用类方法而不是常量,如下所示:

# in your model
def self.source_quota
  {
    'free' => (ENV['FREE_SOURCE_QUOTA'] || '5').to_i,
    'premium' => (ENV['PREMIUM_SOURCE_QUOTA'] || '100').to_i
  }
end

然后在测试中模拟该方法,如下所示:

allow(DataSource).to receive(source_quota)and_return('free' => 2)

1
投票

一种方法是使用 RSpec 的

stub_const
功能。这允许您在示例中将常量值存根为您想要的任何值。

您的测试代码可能看起来像这样

describe 'a thing' do
  before { stub_const('DataSource::SOURCE_QUOTA', {'free' => 2}) } 
  it 'does stuff' do
    expect(DataSource::SOURCE_QUOTA["free"]).to eq 2
    # test code
© www.soinside.com 2019 - 2024. All rights reserved.