Mock process.env using mocked-env

07 Oct 2022 in TIL

When testing values in process.env, they persist for all further tests in your test suite. This can have unwanted side effects, making tests pass or fail unintentionally.

Using mocked-env, you can reset the environment to the pre-test state after every test runs. It works by taking a copy of process.env when you call mockEnv, then restores it once the test has run (afterEach).

Here's an example that shows how environment variables set earlier in the test suite don't persist in to later tests:

javascript
const mockEnv = require("mocked-env");
// Variables to store references to what we need to reset
let restore;
let restoreTest;
beforeEach(() => {
restore = mockEnv({
VALUE_ONE: "Hello",
});
restoreTest = () => {};
});
afterEach(() => {
restore();
restoreTest();
});
test("environment concatenation (world)", async () => {
restoreTest = mockEnv({
VALUE_TWO: "World",
});
expect(concatenateValuesFromEnv("VALUE_ONE", "VALUE_TWO")).toBe(
"Hello World"
);
});
test("environment concatenation (michael)", async () => {
restoreTest = mockEnv({
VALUE_TWO: "Michael",
});
expect(concatenateValuesFromEnv("VALUE_ONE", "VALUE_TWO")).toBe(
"Hello Michael"
);
});
test("environment concatenation (missing value)", async () => {
expect(concatenateValuesFromEnv("VALUE_ONE", "VALUE_TWO")).toBe("Hello ");
});
function concantenateValuesFromEnv(a, b) {
return `${process.env[a]} ${process.env[b]}`;
}

Without using mocked-env, the last test would fail as the returned value would be Hello Michael as VALUE_TWO is set in the previous test, and would not be cleaned up without mocked-env.