What is the best way to write specs for code that depends on environment variables?

I am testing some code that pulls its configuration from environment variables (set by Heroku config vars in production, for local development I use foreman).

What's the best way to test this kind of code with RSpec?

I came up with this:

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

If you don't need to test different values of the environment variables, I guess you could set them in spec_helper instead.


Solution 1:

You also can stub the constant:

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

Or, if you still want the rest of the ENV:

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

Solution 2:

That would work.

Another way would be to put a layer of indirection between your code and the environment variables, like some sort of configuration object that's easy to mock.