我有几个ruby脚本,用rspec测试它们。我把我的环境放在一个env.rb文件中(目前),这样我就可以在本地访问它们,并在生产环境中把它们放在配置变量中。但是当我运行rspec时,我需要不同的环境变量。两个用例:
li9yvcax1#
你可以
ENV["FOO_BAR"] = "baz"
Rails.env.test?
我个人更喜欢只在创建对象并将env var值传递给构造函数时使用ENV var,这样我就可以在不关心ENV的情况下测试对象类,并且我可以通过使用env varAssert创建来测试使用env var替换另一个对象的对象。所以你会改变一些东西,
class Client def initialize @restclient = RestClient::Resource.new(ENV["API_URL"]) endend
class Client
def initialize
@restclient = RestClient::Resource.new(ENV["API_URL"])
end
到
class Client def initialize(url) @restclient = RestClient::Resource.new(url) endend
def initialize(url)
@restclient = RestClient::Resource.new(url)
然后让初始化该示例的东西传递env var的值
def fetch_content client = Client.new(ENV["API_URL"]) # ...end
def fetch_content
client = Client.new(ENV["API_URL"])
# ...
通过这种方式,您可以测试Client类,而无需关心env变量,只需传递任何url,然后可以测试将client示例化为
Client
client
it "uses client" do ENV["API_URL"] = "foo.com" expect(Client).to receive(:new).with(ENV["API_URL"]) subject.fetch_contentend
it "uses client" do
ENV["API_URL"] = "foo.com"
expect(Client).to receive(:new).with(ENV["API_URL"])
subject.fetch_content
更新env var的一个问题是,更改会在测试套件的其余部分中持续存在,如果您不希望它出现在某些测试中,则可能会导致问题,在这些情况下,您可以使用
expect(ENV).to receive(:[]).with("API_URL").and_return("foo.com")
k5ifujac2#
由于ENV是全局状态,因此您希望在每个规格之后重置该值,以避免它在规格之间泄漏:
describe 'enabled?' do around do |example| env_value_before = ENV['MIXPANEL_ENABLED'] ENV['MIXPANEL_ENABLED'] = env_value example.run ENV['MIXPANEL_ENABLED'] = env_value_before end context 'when ENV not set' do let(:env_value) { nil } it 'returns true' do expect(subject.enabled?).to eq(true) end end context 'when ENV is set' do let(:env_value) { '1' } it 'returns false' do expect(subject.enabled?).to eq(false) end endend
describe 'enabled?' do
around do |example|
env_value_before = ENV['MIXPANEL_ENABLED']
ENV['MIXPANEL_ENABLED'] = env_value
example.run
ENV['MIXPANEL_ENABLED'] = env_value_before
context 'when ENV not set' do
let(:env_value) { nil }
it 'returns true' do
expect(subject.enabled?).to eq(true)
context 'when ENV is set' do
let(:env_value) { '1' }
it 'returns false' do
expect(subject.enabled?).to eq(false)
q5lcpyga3#
你可以模拟ENV来返回一个值。这是一个超级干净的一行程序,确保没有任何东西会泄漏到其他测试中:
context 'when LOG_LEVEL is DEBUG' do before { allow(ENV).to receive(:[]).with('LOG_LEVEL').and_return('debug') } ...
context 'when LOG_LEVEL is DEBUG' do
before { allow(ENV).to receive(:[]).with('LOG_LEVEL').and_return('debug') }
...
如果你的代码只看一个ENV变量,这很好用。如果它需要其他var,而这些var对这个测试不感兴趣,你可以允许它们调用original:(虽然这开始感觉有点笨拙)
context 'when LOG_LEVEL is DEBUG' do before do allow(ENV).to receive(:[]).and_call_original allow(ENV).to receive(:[]).with('LOG_LEVEL').and_return('debug') end
before do
allow(ENV).to receive(:[]).and_call_original
allow(ENV).to receive(:[]).with('LOG_LEVEL').and_return('debug')
r3i60tvu4#
如果你经常需要在同一个上下文中存根多个环境变量,可以使用这个帮助器方法:
def stub_env_variable(env_variable, new_value) unless RSpec::Mocks.space.registered?(ENV) # With the condition it allows us to call this helper multiple times for different env variables # in the same context. # # Allowing to return original ENV variables which are not yet stubbed: allow(ENV).to receive(:[]).and_call_original end allow(ENV).to receive(:[]).with(env_variable).and_return(new_value)end
def stub_env_variable(env_variable, new_value)
unless RSpec::Mocks.space.registered?(ENV)
# With the condition it allows us to call this helper multiple times for different env variables
# in the same context.
#
# Allowing to return original ENV variables which are not yet stubbed:
allow(ENV).to receive(:[]).with(env_variable).and_return(new_value)
它允许在相同的上下文中设置多个环境变量,但以更干净的方式,例如:
before do stub_env_variable("VAR_1", 123) stub_env_variable("VAR_2", false) stub_env_variable("VAR_3", "qwerty")end
stub_env_variable("VAR_1", 123)
stub_env_variable("VAR_2", false)
stub_env_variable("VAR_3", "qwerty")
灵感来自@大卫·亨比的回答。
4条答案
按热度按时间li9yvcax1#
你可以
ENV["FOO_BAR"] = "baz"
的上下文中显式设置ENV变量Rails.env.test?
,以设置twilio和其他具有测试特定选项的客户端我个人更喜欢只在创建对象并将env var值传递给构造函数时使用ENV var,这样我就可以在不关心ENV的情况下测试对象类,并且我可以通过使用env varAssert创建来测试使用env var替换另一个对象的对象。
所以你会改变一些东西,
到
然后让初始化该示例的东西传递env var的值
通过这种方式,您可以测试
Client
类,而无需关心env变量,只需传递任何url,然后可以测试将client
示例化为更新env var的一个问题是,更改会在测试套件的其余部分中持续存在,如果您不希望它出现在某些测试中,则可能会导致问题,在这些情况下,您可以使用
k5ifujac2#
由于ENV是全局状态,因此您希望在每个规格之后重置该值,以避免它在规格之间泄漏:
q5lcpyga3#
你可以模拟ENV来返回一个值。这是一个超级干净的一行程序,确保没有任何东西会泄漏到其他测试中:
如果你的代码只看一个ENV变量,这很好用。如果它需要其他var,而这些var对这个测试不感兴趣,你可以允许它们调用original:(虽然这开始感觉有点笨拙)
r3i60tvu4#
如果你经常需要在同一个上下文中存根多个环境变量,可以使用这个帮助器方法:
它允许在相同的上下文中设置多个环境变量,但以更干净的方式,例如:
灵感来自@大卫·亨比的回答。