为依赖于环境变量的代码编写规范的最佳方式是什么



我正在测试一些从环境变量中提取配置的代码(在生产中由Heroku配置变量设置,对于本地开发,我使用foreman)。

用RSpec测试这类代码的最佳方法是什么?

我想出了这个:

before :each do
    ENV.stub(:[]).with("AWS_ACCESS_KEY_ID").and_return("asdf")
    ENV.stub(:[]).with("AWS_SECRET_ACCESS_KEY").and_return("secret")
end

如果您不需要测试环境变量的不同值,我想您可以在spec_helper中设置它们。

您还可以存根常量:

stub_const('ENV', {'AWS_ACCESS_KEY_ID' => 'asdf'})

或者,如果您仍然想要ENV:的其余部分

stub_const('ENV', ENV.to_hash.merge('AWS_ACCESS_KEY_ID' => 'asdf'))

那就行了。

另一种方法是在代码和环境变量之间放置一层间接层,比如某种易于模拟的配置对象。

此语法适用于我:

module SetEnvVariable
  def set_env_var(name, value)
   # Old Syntax
   # ENV.stub(:[])
   # ENV.stub(:[]).with(name).and_return(value)
   allow(ENV).to receive(:[]) # stub a default value first if message might be received with other args as well.
   allow(ENV).to receive(:[]).with(name).and_return(value)
  end
end

正如Heroku所建议的,您可以使用Foreman的.env文件来存储用于开发的环境变量。

如果你这样做,你可以使用foreman run来运行你的规格:

foreman run bundle exec rspec spec

如果您在测试期间使用dotenv设置环境,但需要为特定测试修改env变量,那么以下方法可能很有用。

与存根ENV相比,一个更简单的方法是在测试期间替换环境,然后像这样恢复:

with_environment("FOO" => "baz") do
  puts ENV.fetch("FOO")
end

使用这样的助手:

module EnvironmentHelper
  def with_environment(replacement_env)
    original_env = ENV.to_hash
    ENV.update(replacement_env)
    yield
  ensure
    ENV.replace(original_env)
  end
end

通过使用ensure,即使测试失败,也可以恢复原始环境。

设置&在测试期间修改环境变量,包括清除ENV、替换测试前后的值,以及ClimateControl等gem。

您可以使用https://github.com/littleowllabs/stub_env以实现这一点。它允许您存根单个环境变量,而无需按照解决方案的建议存根所有环境变量。

安装gem,然后写入

before :each do
  stub_env('AWS_ACCESS_KEY_ID', 'asdf')
  stub_env('AWS_SECRET_ACCESS_KEY','secret')
end

我会避免使用ENV.stub(:[])——如果其他东西正在使用ENV,比如prick,它就不起作用(您会得到一个关于需要存根DISABLE_PRY的错误)。

CCD_ 10工作良好,正如已经指出的那样。

您想要的是dotenv宝石。

正如@ciastek所建议的,在foreman下运行测试在从CLI运行规范时效果非常好。但这并不能帮助我在Sublime Text 2中使用Ruby Test运行规范。Dotenv完全透明地做你想做的事。

最新更新