Search code examples
next.jsjestjsreact-testing-librarynext.js13

Next 13 Jest test fails using 'next/headers'


I am using Next.JS 13, and have a component which is using

import { cookies } from 'next/headers';

The simplified component:

import { cookies } from 'next/headers';

function Simple() {
  console.log({ cookies });
  return <div>Simple</div>;
}

export default Simple;

and the simplified test:

import { render } from '@testing-library/react';

import Simple from './Simple';

describe('<Simple />', () => {
  it('should render Simple component', () => {
    render(<Simple />);
  });
});

When I have any reference to the cookies, in this case

  console.log({ cookies });

I always get the following error when running jest tests:

     x NEXT_RSC_ERR_CLIENT_IMPORT: next/headers
       ,-[1:1]
     1 | import { cookies } from 'next/headers';
       : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     2 | 
     3 | function Simple() {
     4 |   console.log({ cookies });

Any ideas how to fix it?

I have tried mocking the 'next/headers' with jest.mock, like so, but to no avail:

jest.mock('next/headers', () => ({
  cookies: jest.fn(),
}));

My jest.config.js

const nextJest = require('next/jest');

const createJestConfig = nextJest({
  dir: './',
});

const customJestConfig = {
  setupFilesAfterEnv: ['./.jest/setup.js'],
  testEnvironment: 'jest-environment-jsdom',
};

module.exports = async () => ({
  ...(await createJestConfig(customJestConfig)()),
});

My ./jest/setup.js

require('jest-fetch-mock').enableMocks();

import '@testing-library/jest-dom';

Package versions

    "next": "13.1.0",
    "jest": "^29.3.1",
    "jest-environment-jsdom": "^29.3.1",
    "jest-fetch-mock": "^3.0.3",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",

Solution

  • I have observed that the issue stems from the next/jest setup, where SWC is used as the transform. Therefore made couple of changes:

    Added new jest.config.js file with the following configuration:

    module.exports = {
        setupFilesAfterEnv: ["./jest/setup.js"],
        testEnvironment: "jest-environment-jsdom",
        transform: {
            "^.+\\.(js|jsx|ts|tsx)$": ["babel-jest", { presets: ["next/babel"] }],
        },
    };
    

    The purpose of this new configuration file is to replace SWC with Babel for transforming JS, JSX, TS, and TSX files.

    Added server-only.js file to mock directory to simulate the server components. This mock prevents the error from being thrown.

    module.exports = {};
    

    Codesandbox or github repo for example