Home > Net >  Jest Module Mock with ECMAScript Modules
Jest Module Mock with ECMAScript Modules

Time:08-21

Using the documentation (https://jestjs.io/docs/ecmascript-modules) as a guide, I have written the following:

package.json:

{
  "scripts": {
    "watch-test": "jest ./test --verbose --watch"
  },
  "dependencies": {
    "ethers": "^5.6.9"
  },
  "devDependencies": {
    "jest": "^28.1.3"
  },
  "jest": {
    "verbose": true,
    "transform": {}
  },
  "type": "module"
}

test/test.js:

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

jest.mock('ethers', () => ({ethers: 'Hello, world!'}));
console.log(ethers);

Use the following to execute the test: npm i && NODE_OPTIONS=--experimental-vm-modules npm run watch-test;. The output is console.log {Signer: [Getter],Wallet: [Getter],... and so on but I wish it said something like console.log "Hello, world!".

It appears that the ethers module (or the ethers object in the module?) is not getting mocked at all. I tried moving the jest.mock call above the import (which shouldn't be necessary because of jest hoisting), but that didn't help anything.

How do I mock the ethers module using jest when using ECMAScript modules configuration?

CodePudding user response:

Although hoisting is done in common JS, it is not done using ECMAScript Modules, so instead of importing mocked modules, you must use dynamic import to import them after the mocking.

test/test.js:

import {jest} from '@jest/globals';
jest.mock('ethers', () => ({ethers: 'Hello, world!'}));
const {ethers} = await import('ethers');

test('do it', ()=> {
    expect(ethers).toEqual("Hello, world!");
});

package.json:

{
    "scripts": {
        "watch-test": "jest ./test --verbose --watch"
    },
    "dependencies": {
        "ethers": "^5.6.9"
    },
    "devDependencies": {
        "jest": "^28.1.3"
    },
    "jest": {
        "verbose": true,
        "testMatch": [
            "<rootDir>/test/**/*.?(c)js"
        ],
        "transform" : {}
    },
    "type": "module"
}

("testMatch": "test/**" doesn't work, you must prefix with <rootDir> or **; I'm not sure why.)

And invoked as stated in the question.

This conversation got me on the right track: https://github.com/facebook/jest/issues/13135

  • Related