How to load environment variable in tests with Next.js?

Viewed 2064

I'm trying to run a simple test with JavaScript as below.

import React from 'react';
import Customization from 'components/onboarding/customization';
import '@testing-library/jest-dom';
import { render, screen, fireEvent } from '@testing-library/react';

describe('customization render', () => {
  it('should render the Hero page with no issue', () => {
    render(<Customization />);

    const heading = screen.getByText(
      /All the Moodmap at one place!/i
    );

    expect(heading).toBeInTheDocument();
  });
  it("should call onCLick method on click", () => {
    const mockOnClick = jest.fn()

    const {container} = render(<Customization />);

    const button = getByTestId(container, 'alreadyDownloaded');
    fireEvent.click(button);
    expect(mockOnClick).toHaveBeenCalledTimes(1)


    // const mockOnClick = jest.fn()
    // const utils = render(<Customization onClick={mockOnClick} />)
    // fireEvent.click(screen.getByText(/already downloaded ⟶/i))
    // expect(mockOnClick).toHaveBeenCalledTimes(1)
  })
});

When running the tests I'm getting this error

No google analytics trackingId defined

   8 |   debug: process.env.NODE_ENV !== 'production',
   9 |   plugins: [
> 10 |     googleAnalyticsPlugin({
     |     ^
  11 |       trackingId: process.env.NEXT_PUBLIC_GA_TRACKING_ID,
  12 |     }),

How do I make this error go away - surely it shouldn't require Google Analytics code given the above, it's not in production when running the test?

Update

So I need to make sure the .env file is being loaded!

In my package.json I've got this Jest setup:

"jest": {
    "testMatch": [
      "**/?(*.)(spec|test).?(m)js?(x)"
    ],
    "moduleNameMapper": {
      "\\.(css|less|scss)$": "identity-obj-proxy"
    },
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "rootDir": "src",
    "moduleFileExtensions": [
      "js",
      "jsx",
      "mjs"
    ],
    "transform": {
      "^.+\\.m?jsx?$": "babel-jest"
    },
    "coverageThreshold": {
      "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80,
        "statements": -10
      }
    }
  },

updated code to use jest.setup - can't get env to load

So

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import "@testing-library/jest-dom";

configure({
    adapter: new Adapter()
});

module.exports = {
  testMatch: [
    "**/?(*.)(spec|test).?(m)js?(x)"
  ],
  moduleNameMapper: {
    "\\.(css|less|scss)$": "identity-obj-proxy"
    },
  moduleDirectories: [
    "node_modules",
    "src"
    ],
    rootDir: "src",
  moduleFileExtensions: [
    "js",
    "jsx",
    "mjs"
  ],
  transform: {
    "^.+\\.m?jsx?$": "babel-jest"
    },
coverageThreshold: {
    "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80,
        "statements": -10
    }
    },
    setupFiles: ["../<rootDir>/.config.env.test"]

};

The environment variable files is here:

process.env.NEXT_PUBLIC_GA_TRACKING_ID=xxx

And this is the code that is not loading the environment variables properly.

import Analytics from 'analytics';
import googleAnalyticsPlugin from '@analytics/google-analytics';
import Router from 'next/router';

    // Initialize analytics and plugins
    // Documentation: https://getanalytics.io
    const analytics = Analytics({
      debug: process.env.NODE_ENV !== 'production',
      plugins: [
        googleAnalyticsPlugin({
          trackingId: process.env.NEXT_PUBLIC_GA_TRACKING_ID,
        }),
      ],
    });
2 Answers

During your tests you can leverage loadEnvConfig from @next/env to make sure your environment variables are loaded the same way Next.js does.

First setup a .env.test to be used during the tests.

NEXT_PUBLIC_GA_TRACKING_ID=ga-test-id

Next, create a Jest global setup file if you don't have one yet, and reference it in your jest.config.js.

// jest.config.js

module.exports = {
    //...
    setupFilesAfterEnv: ['./jest.setup.js'],
};

Then add the following code into your Jest global setup file.

// jest.setup.js
import { loadEnvConfig } from '@next/env'

loadEnvConfig(process.cwd())

This message means that the trackingId is not defined. As you can see it read from the process.env. You need to create this file in the root of your project and call it .env. Note that the dot is at the beginning of the filename. The content of the file should be as follow:

NEXT_PUBLIC_GA_TRACKING_ID=insert-key-here

If your env file is not being read by jest you can do the following:

// In jest.config.js : 

module.exports = {
 ....
    setupFiles: ["<rootDir>/test/setup-tests.ts"]
}


// The file test/test-setup.ts:

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

You can also check this article for more details.

Related