Mocking process.env

How to quickly mock process.env during unit testing.

Often, the behavior of the program is controlled by the environment variables at its startup. In Node, all these variables are stored in process.env object, where is value is cast as string ⚠️ (this makes process.env different from "regular" JavaScript objects, because we have to take it into account).

If you want to see the process.env just execute node -e 'console.log(process.env)' from the terminal. Notice how all values are strings?

1
2
3
4
5
6
7
{
...
XPC_SERVICE_NAME: '0',
HOME: '/Users/gleb',
SHLVL: '1',
...
}

I love sinon.js, so my first approach was to use it to mock process.env. Sinon allows me to quickly stub existing process.env properties during unit testing. For example, the following works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const assert = require('assert')
const sinon = require('sinon')
let sandbox = sinon.createSandbox()

beforeEach(() => {
sandbox.stub(process.env, 'USER').value('test-user')
})

it('has expected user', () => {
assert(process.env.USER === 'test-user', 'wrong user')
})

afterEach(() => {
sandbox.restore()
})

Great, but what about properties that might not exist in process.env before the test? After searching through the docs and GitHub issues, I could only conclude that Sinon does not allow you to add a mock property temporarily. To the NPM registry search! I found burl/mock-env, but its syntax was really weird. So I finally coded mocked-env, check it out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const mockedEnv = require('mocked-env')
let restore
beforeEach(() => {
// pass object with modified / added / deleted values
// it will be merged into existing process.env
restore = mockedEnv({
USER: 'test-user',
PWD: undefined, // will be deleted from process.env
})
})

it('works', () => {
assert(process.env.USER === 'test-user', 'wrong user')
assert(process.env.PWD === undefined, 'wrong PWD')
})

afterEach(() => {
// don't forget to restore the old process.env
restore()
})

Happy testing!

Related posts