next.js: Misleading documentation: variables in .env and .env.test are not being loaded in test environment

Bug report

Describe the bug

According to these docs:

Next.js allows you to set defaults in .env (all environments)

Further down on the same page:

Apart from development and production environments, there is a 3rd option available: test. In the same way you can set defaults for development or production environments, you can do the same with .env.test file for testing environment

But variables in .env and .env.test are not being loaded when running tests.

To Reproduce

Basic setup and .env:

  1. create-next-app -e with-jest and enter a name
  2. cd <name>
  3. echo MY_VAR=my_value >.env
  4. cat >__tests__/env.js <<EOF
    describe("environment variables", () => {
      it("loads variables from .env in the test environment", () => {
        expect(process.env.MY_VAR).toBe("my_value");
      });
    });
    EOF
    
  5. npm run test:ci -- env

The test fails: process.env.MY_VAR is undefined.

.env.test:

  1. mv .env .env.test
  2. npm run test:ci -- env

The test fails: process.env.MY_VAR is undefined.

Expected behavior

The test should pass in both situations (with the file named either .env or .env.test). At least, if I’m understanding the docs correctly and I’m not doing anything silly.

System information

  • OS: Ubuntu
  • Version of Next.js: 9.5.5
  • Version of Node.js: 12.18.1

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 23 (13 by maintainers)

Commits related to this issue

Most upvoted comments

@tremby see: https://jestjs.io/docs/en/configuration#globalsetup-string e.g.

jest.config.js

module.exports = {
  ...
  globalSetup: '<rootDir>/test/setupEnv.ts',
}

test/setupEnv.ts

import { loadEnvConfig } from '@next/env'

export default async () => {
  loadEnvConfig(process.env.PWD)
}

I too have just noticed this. NODE_ENV is set to to test, but when running Jest unit tests the .env.test file is not loaded. The docs do indicate that they should.

As per @erkde comment, I have fixed this with by loading the env files in jest.config.js

const { loadEnvConfig } = require('@next/env')
loadEnvConfig(process.env.PWD)

As of v9.5.5, you can just do

import { loadEnvConfig } from '@next/env'

export default async () => {
  loadEnvConfig(process.env.PWD)
}

if you add that your jest setup (e.g. globalSetup), should be good to go

I needed the .env.test file loaded for both Jest and out Cypress integration tests. My workaround was to use https://www.npmjs.com/package/dotenv-load which behaves as expected.

My temporary workaround has been to add a global setup file in my Jest configuration:

/**
 * @file jest.config.js
 */

module.exports = {
  globalSetup: '<rootDir>/test/setup.ts',
};

and to load a particular environment configuration with dotenv:

/**
 * @file test/setup.ts
 */

import dotenv from 'dotenv';

dotenv.config({ path: '.env.test' });

I know it doesn’t solve the problem, but hopefully it can be helpful in the meantime.

Also, you may be able to run dotenv.config(...) with multiple paths to load in a few configs (please note I have not tested this):

dotenv.config({ path: '.env' });
dotenv.config({ path: '.env.test' });

My workaround was actually simpler (but arguably worse) since I only need two very specific things set: I forego the .env files for test purposes and just directly set process.env.whatever = “whatever” in the setup file. Does the trick.