Search code examples
javascriptnode.jsjestjsenvironment-variablesnodeenv

Jest + process.env.NODE_ENV not testing properly


I have a config file that changes a variable based on the process.env.NODE_ENV here is the function:

const { hostname } = window.location

let USE_DEV_TOOLS = false
if (
  hostname === 'qa.example.com' ||
  hostname === 'dev.example.com' ||
  NODE_ENV !== 'production'
) {
  USE_DEV_TOOLS = true
}

In my test I want to test that if NODE_ENV is production, USE_DEV_TOOLS returns false however, if I try to change the NODE_ENV it updates after getting the variable.

import config from 'consts/config'
describe('Environment variables', () => {
  const ORIGINAL_ENV = process.env
  beforeEach(() => {
    jest.resetModules()
    process.env = { ...ORIGINAL_ENV }
  })

  afterAll(() => {
    process.env = ORIGINAL_ENV
  })

  it('production does not use dev tools', () => {
    process.env = { NODE_ENV: 'production' }

    // console logs properly, but is changing after I get config
    console.log(process.env.NODE_ENV) 

    expect(config.USE_DEV_TOOLS).toBe(false)
  })
}) 

Solution

  • Use es6 import to import the module, the code in the module will be executed immediately, at this time process.env.NODE_ENV environment has not been modified.

    So you should use require to require the module after modifying the process.env.NODE_ENV in the test case.

    E.g.

    config.js:

    const { hostname } = window.location;
    
    console.log('config loaded');
    
    let USE_DEV_TOOLS = false;
    if (hostname === 'qa.example.com' || hostname === 'dev.example.com' || process.env.NODE_ENV !== 'production') {
      USE_DEV_TOOLS = true;
    }
    
    export default { USE_DEV_TOOLS };
    

    config.test.js:

    describe('Environment variables', () => {
      const ORIGINAL_ENV = process.env;
      beforeEach(() => {
        jest.resetModules();
        process.env = { ...ORIGINAL_ENV };
      });
    
      afterAll(() => {
        process.env = ORIGINAL_ENV;
      });
    
      it('production does not use dev tools', () => {
        process.env = { NODE_ENV: 'production' };
        console.log(process.env.NODE_ENV);
        const config = require('./config').default;
    
        expect(config.USE_DEV_TOOLS).toBe(false);
      });
    });
    

    test result:

     PASS  examples/66555582/config.test.js
      Environment variables
        ✓ production does not use dev tools (10 ms)
    
      console.log
        production
    
          at Object.<anonymous> (examples/66555582/config.test.js:16:13)
    
      console.log
        config loaded
    
          at Object.<anonymous> (examples/66555582/config.js:3:9)
    
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        1.392 s, estimated 4 s