Accessing environment variables directly with process.env.<variable-name>
can, in certain circumstances give you a performance hit. So as a general rule I declare environment variables ‘up top’ like below.
'use strict'// npm dependencies
const app = require('express')()// constants
const {NODE_PORT, NODE_ENV} = process.env...
The above method can also make for more readable code (IMHO), so it can be a double win. However how do you then test code which has different code paths dependent on which environment variables are set and/or their values?
It took me a little while to come up with a pattern that I liked, but I thought I’d share it now I have.
So trying to test the following example function.
'use strict'// constants
const {USE_OTHER_CODE_PATH} = process.envmodule.exports = () => {
if (USE_OTHER_CODE_PATH !== 'true') {
return 'Took the default code path'
} else {
return 'Took the other code path'
}
}
You can easily test one code path by setting the correct environment variables for that path in your test config, but how do you then test the second path?
If you just simply set process.env.USE_OTHER_CODE_PATH = 'true'
it will have no affect. The constant USE_OTHER_CODE_PATH
in your module was set when the module was loaded.
You need to force the reload of the module, this is where the proxyquire module comes in handy. Using it’s ‘.noPreserveCache()’ mode allows you to reload a library in each test you want to, without affecting other tests.
'use strict'// npm dependencies
const {expect} = require('chai')
const proxyquire = require('proxyquire').noPreserveCache()describe('example.js', () => {
let initialEnvVar it(`USE_OTHER_CODE_PATH is not set it takes the default path`, () => {
process.env.USE_OTHER_CODE_PATH = undefined
const example = proxyquire('./example.js', {})
expect(example()).to.equal('Took the default code path')
}) it(`USE_OTHER_CODE_PATH is 'true' it takes the other path`, () => {
process.env.USE_OTHER_CODE_PATH = 'true'
const example = proxyquire('./example.js', {})
expect(example()).to.equal('Took the other code path')
}) beforeEach(() => {
initialEnvVar = process.env.USE_OTHER_CODE_PATH
}) afterEach(() => {
process.env.USE_OTHER_CODE_PATH = initialEnvVar
})})