【问题标题】:What are the possible bad consequences of changing ENV to 'production' in the middle of a test?在测试过程中将 ENV 更改为“生产”可能会产生哪些不良后果?
【发布时间】:2020-05-18 14:55:00
【问题描述】:

我写了一个只需要在生产环境中运行的代码。在我的规范/测试文件中,测试此代码时,我必须将 ENV 变量更改为“生产”,以便代码正常工作。

代码:

do_something if Rails.env.production?

规格:

context "some context" do

  before { Rails.env = 'production' }

  # test something

end

我的问题是:这种方法有问题吗?其他选项是更改代码以在“生产”或“测试”环境中运行。这在某种程度上是“更好”的吗?我觉得我不应该在测试中改变环境,但不知道这是否正确以及为什么。

【问题讨论】:

  • 可能有很长的潜在副作用列表,例如 Rails 连接到错误的数据库。
  • do_something 应该被隔离,以便您可以在任何环境下测试它。即使这意味着对某些部分进行存根。
  • 一个可能非常危险的副作用可能是您对生产数据库运行测试 - 根据您的测试设置 - 可能会导致生产数据库表截断...
  • 我知道这不是你要问的......但是为了避免将来出现这种情况(或者如果它是一个新项目,请在此处解决)永远不要在实际代码中使用环境名称。而是使用因环境而异的设置。例如,这里的if Rails.env.production? 可以是if Settings.something_enabled?,您可以简单地为该规范存根。

标签: ruby-on-rails ruby testing rspec


【解决方案1】:

不要在测试过程中改变环境,而是创建一个 ActiveSupport:StringInquirer(Rails.env 的类)的实例并使用它:

 class MyClassThatNeedsEnvironment
     def initialize(env)
       @env = env
     end

     def foo
       do_something if @env.production?
     end
 end

测试示例:

    context "test" do

    let(:my_class_instance) {
        env_as_string = Rails.env.to_s    
MyClassThatNeedsEnvironment.new(ActiveSupport::StringInquirer.new(env_as_string))

    }

    end

    context "production" do
      let(:my_class_instance) {
        env_as_string = 'production'   

    MyClassThatNeedsEnvironment.new(ActiveSupport::StringInquirer.new(env_as_string))

    }
    end

这不会产生副作用并保留依赖倒置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 2014-08-04
    相关资源
    最近更新 更多