jest.mock of ES6 class yields ReferenceError: require is not defined

Viewed 4469

I'm trying to create an automatic mock using jest in my ES6 javascript project.

I'm using node v15.0.1, and jest 26.6.0 on ubuntu 18.04.5.

I have a test file containing the following code:

import RenderBuffer from './renderbuffer.js'

jest.mock('./renderbuffer.js');

beforeEach(() => {
    RenderBuffer.mockClear();
});

When I run the test I run into the following issue:

ReferenceError: require is not defined

      4 | 
      5 | beforeEach(() => {
    > 6 |     RenderBuffer.mockClear();
        |       ^
      7 | });
      8 | 

The error is surprising to me as I'm not using a require statement.

My package.json config contains the following:

"type": "module",
    "main": "src/index.js",
    "devDependencies": {
        "jest": "^26.5.3",
        "jest-canvas-mock": "^2.3.0"
    },
    "jest": {
        "setupFiles": ["jest-canvas-mock"]
    },
    "scripts": {
        "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
        "test-coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage"
    }

Any ideas as to what the root cause of this issue is?

1 Answers

You have to disable any source code transformations in order to make it working by setting

{
  transform: {}
}

in your Jest configuration file. By default transform option is configured to use babel-jest. Please refer to this Jest documentation section for more details. Also note that you should import jest explicitly:

import { jest } from '@jest/globals';

Unfortunatelly, it can still have some issues running your tests as other commenters already mentioned. Probably, one should follow this issue to keep tracking changes being made in Jest for ESM support.

For example, I was unlucky to mock static module imports at the moment (version 26.6.2):

jest.(do|un)mock

Since ESM has different "stages" when evaluating a module, jest.mock will not work for static imports. It can work for dynamic imports though, so I think we just have to be clear in the docs about what it supports and what it doesn't.

jest.mock calls are hoisted, but that doesn't help in ESM. We might consider transforming import 'thing' to import('thing') which should allow hoisting to work, but then it's async. Using top-level await is probably a necessity for such an approach. I also think it's invasive enough to warrant a separate option. Something to discuss - we don't need to support everything jest.mock can for for an initial release.

Related