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