I have the following code below which returns certain data depending on NODE_ENV:
config.js
export const Config = (() => { let data; switch (process.env.NODE_ENV) { case 'development': data = '123'; break; case 'production': data = '456' break; default: break; } return { data }; })();
This works well in my component when I set NODE_ENV. However in my test, I keep getting undefined as a result.
config.test.js
describe('Config', () => { test('returns correct data if NODE_ENV is development', () => { process.env = { ...process.env, NODE_ENV: 'development' }; expect(Config.data).toBe('123'); // returns undefined, expected '123' }); test('returns correct data if NODE_ENV is production', () => { process.env = { ...process.env, NODE_ENV: 'production' }; expect(Config.data).toBe('456'); // returns undefined, expected '456' }); });
Again, Config.data
works fine in my React component when I start it up, but I guess I need to somehow initialize this for it to work in my tests? Any advice would be appreciated!
Advertisement
Answer
First of all, you need to make sure the config
module is imported after setting the process.env
. So you need to use const { Config } = require('./config')
rather than import { Config } from './config';
Because imports are hoisted, and when the IIFE execute, the process.env
is not prepared.
Another note is module caching.
Modules are cached after the first time they are loaded. This means (among other things) that every call to
require('foo')
will get exactly the same object returned, if it would resolve to the same file.
Provided
require.cache
is not modified, multiple calls torequire('foo')
will not cause the module code to be executed multiple times. This is an important feature. With it, “partially done” objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.
There is an IIFE in your config module, it only executes once when you require('./config')
multiple times. The value of process.env
in IIFE is also cached. So, you need to use jest.resetModules() to clear the module cache.
E.g.
config.js
:
export const Config = (() => { let data; console.log(process.env.NODE_ENV); switch (process.env.NODE_ENV) { case 'development': data = '123'; break; case 'production': data = '456'; break; default: break; } return { data }; })();
config.test.js
:
describe('Config', () => { let Config; beforeEach(() => { jest.resetModules(); }); test('returns correct data if NODE_ENV is development', () => { process.env = { ...process.env, NODE_ENV: 'development' }; Config = require('./config').Config; expect(Config.data).toBe('123'); }); test('returns correct data if NODE_ENV is production', () => { process.env = { ...process.env, NODE_ENV: 'production' }; Config = require('./config').Config; expect(Config.data).toBe('456'); }); });
Test result:
PASS stackoverflow/71733750/config.test.ts Config ✓ returns correct data if NODE_ENV is development (15 ms) ✓ returns correct data if NODE_ENV is production (2 ms) console.log development at stackoverflow/71733750/config.ts:29:11 console.log production at stackoverflow/71733750/config.ts:29:11 -----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -----------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 100 | 100 | config.ts | 100 | 100 | 100 | 100 | -----------|---------|----------|---------|---------|------------------- Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 1.354 s
You can try to remove jest.resetModules()
to check the logs.