在 rspec 中设置 RAILS_ENV

Set RAILS_ENV in rspec

请考虑以下代码:

class MyModel
  validate my_validation unless ENV["RAILS_ENV"] == "test" 
end

我们有一个验证将对测试套件的巨大部分产生重大影响。我只希望它在产品中执行,而不是在 运行 测试套件时执行*...除了关于此验证的实际测试。

因此,在测试验证时,我需要将 ENV["RAILS_ENV"] 设置为其他值,然后再进行测试。我在我的 my_model_spec.rb-file:

中试过这个
it "tests the validation" do
  ENV["RAILS_ENV"] = "development"
  
  # Tests the validation..
  
  ENV["RAILS_ENV"] = "test"
end

这会在规范文件中设置变量,但在 my_model.rb 中进行检查的地方 ENV["RAILS_ENV"] 仍然 returns“测试”。

有没有办法在 SPEC 文件中实现 ENV["RAILS_ENV"] 的声明,并在示例 运行 期间执行模型代码时仍然设置它?


强制性:

validate my_validation unless ENV["RAILS_ENV"] == "test" 

在 99.9% 的情况下,这确实不是一个好主意。

只是觉得我需要说清楚,以防未来的读者看到这个 post 并得到有趣的想法......(最好更新测试套件以保持有效,例如通过更改工厂。)

Is there a way to achieve the declaration of ENV["RAILS_ENV"] in the SPEC-file

是 - 您可以存根值:

allow(ENV).to receive(:[]).with('RAILS_ENV').and_return('development')

您还可以考虑其他一些方法。

例如,为了运行宁此测试,为什么不直接调用方法?

record = MyModel.new # or using FactoryBot.build / whatever
record.my_validation

或者,您可以添加模型属性以强制-运行 验证:

class MyModel
  attr_accessor :run_my_validation
  validate my_validation if ENV["RAILS_ENV"] != "test" || run_my_validation
end

# and in the test:
record = MyModel.new # or using FactoryBot.build / whatever
record.run_my_validation = true
expect(record.valid?).to be_true

要从生产代码中消除 rails 环境检查,您可以考虑的另一种方法是设置 environment-specific configuration value。同样,您可以在规范中存根:

class MyModel
  validate my_validation if Rails.configuration.run_my_model_validation
end

# and in the test:
allow(Rails.configuration).to receive(:run_my_model_validation).and_return(true)

上述的另一个好处是您可以在开发模式下启用验证,而无需对应用程序进行任何代码更改。