I have an app that depends on environmental variables like:
const APP_PORT = process.env.APP_PORT || 8080;
and I would like to test that for example:
- APP_PORT can be set by node env variable.
- or that an
express
app is running on the port set with process.env.APP_PORT
How can I achieve this with Jest? Can I set these process.env
variables before each test or should I mock it somehow maybe?
The way I did it can be found in this SO question.
It is important to resetModules before each test and then dynamically import the module inside the test:
describe('environmental variables', () => {
const OLD_ENV = process.env;
beforeEach(() => {
jest.resetModules() // this is important
process.env = { ...OLD_ENV };
delete process.env.NODE_ENV;
});
afterEach(() => {
process.env = OLD_ENV;
});
test('will receive process.env variables', () => {
// set the variables
process.env.NODE_ENV = 'dev';
process.env.PROXY_PREFIX = '/new-prefix/';
process.env.API_URL = 'https://new-api.com/';
process.env.APP_PORT = '7080';
process.env.USE_PROXY = 'false';
const testedModule = require('../../config/env').default
// ... actual testing
});
});
Depending on how you can organize your code, another option can be to put the env variable within a function that's executed at runtime.
In this file, the env var is set at import time, and requires dynamic require
s in order to test different env vars (as described in this answer):
const env = process.env.MY_ENV_VAR;
const envMessage = () => `MY_ENV_VAR is set to ${env}!`;
export default myModule;
In this file, the env var is set at envMessage
execution time, and you should be able to mutate process.env directly in your tests:
const envMessage = () => {
const env = process.env.MY_VAR;
return `MY_ENV_VAR is set to ${env}!`;
}
export default myModule;
Jest test:
const vals = [
'ONE',
'TWO',
'THREE',
];
vals.forEach((val) => {
it(`Returns the correct string for each ${val} value`, () => {
process.env.MY_VAR = val;
expect(envMessage()).toEqual(...