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

Created on 15 Oct 2020  路  16Comments  路  Source: vercel/next.js

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 < 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

All 16 comments

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

So the docs are out of date?

So the docs are out of date?

maybe, 9.5.5 is only out a few days

Well the problem also exists on 9.5.4. It's either an application bug or a documentation bug regardless, unless I have something wrong.

Next.js does not set up your test environment currently so it can't load environment variables for you. You can boot up the Next.js server though which loads the environment variables:

const next = require('next')
// `.env` / `.env.test` is loaded during initialization.
const app = next()

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)

A documentation bug then.

Regarding booting Next, do you suggest doing that globally (such as in jest config) or per test file which needs it?

For my purposes, it made sense to make the change globally as I had an env var that disables auth checks during tests.

The loading if .env.test does work for my Cypress tests as documented

But only after booting Next, right? That ought to be documented.

Sorry, what do you mean by 'booting Next'?

As above in @timneutkens's comment:

You can boot up the Next.js server though which loads the environment variables:

const next = require('next')

Ah. Sorry, I didn't seem to need this step. Programmatically setting the env vars using loadEnvConfig was enough

Right, so it sounds like either loadEnvConfig or require('next') get the vars loaded up. Just saying that the docs should mention this when it talks about env vars for tests.

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.

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.

Was this page helpful?
0 / 5 - 0 ratings