Stubbing environment variables in RSpec
To test code based on some environment variables configuration, you usually need a way to define environment variables on an individual test case level and be sure this configuration won't leak from test to test.
In this scenario, RSpec's method stubbing comes in handy:
# spec/support/env_helpers.rb
module EnvHelpers
def stub_env(variable_name, value)
allow(ENV).to receive(:[]).and_call_original
allow(ENV).to receive(:[]).with(variable_name).and_return(value)
allow(ENV).to receive(:fetch).and_call_original
allow(ENV).to receive(:fetch).with(variable_name).and_return(value)
end
RSpec.configure { |config| config.include self }
end
Require this module from spec/spec_helper.rb
for new helpers availability in the specs:
require_relative "./support/env_helpers"
Usage example with custom configuration file in a Rails project:
# config/external_api.yml
development:
api_key: "non_secret_api_key"
test:
api_key: <%= ENV["API_KEY"] %>
production:
api_key: <%= ENV["API_KEY"] %>
The spec:
# specs/configuration/external_api_spec.rb
RSpec.describe "external api configuration" do
subject(:configuration) { Rails.application.config_for("external_api") }
context "with sample configuration" do
before { stub_env("API_KEY", "test_api_key") }
it { expect(configuration.api_key).to eq("test_api_key") }
end
context "with no configuration" do
it { expect(configuration.api_key).to be_nil }
end
context "with direct environment variables access" do
before { stub_env("SAMPLE", "value") }
it { expect(ENV["SAMPLE"]).to eq("value") }
it { expect(ENV.fetch("SAMPLE")).to eq("value") }
end
end
References:
Somewhat related:
- Comparing Rails routing configuration with git
- Calling the original instance method after overriding in Ruby
- Fixing ActiveRecord::UnknownMigrationVersionError
- How to list all validators in a Rails model
- Reapplying Rails DB migration
- Downloading CleanShot images with Ruby
- Customizing enum fields order for ActiveRecord
- Updating Ruby with asdf
- Preserving backtrace during exceptions wrapping in Ruby
- RSpec snippet for Sublime Text
- Rails class_names helper
- Updating gems
- Hot to change password manually with Rails and Devise