jest: [Bug]: jest.mock not working with ESM support activated
Version
28.1.3
Steps to reproduce
- Clone my repo: https://github.com/iamWing/jest-esm-mock-issue
npm I
npm run start
to verify Electron app shows up without issuenpm t
to run jest for the error
Expected behavior
Expecting Jest to mock functions app.on
, app.whenReady
and component BrowserWindow
from electron
, then execute the test cases with the mocked functions.
Actual behavior
Encountered TypeError: Cannot read properties of undefined (reading 'whenReady')
when trying to run the test cases.
One possible reason I can think of is the imported module is being executed before jest.mock('electron', ...)
in main.spec.js
, hence Node is executing the line app.whenReady()
in main.cjs
with the non-mocked version.
Additional context
I originally tested with TypeScript & ts-jest
with ESM support activated. The error I encountered there is very similar, so that I believe the error is from jest
instead of ts-jest
. See my comment on #10025 (https://github.com/facebook/jest/issues/10025#issuecomment-1214297747)
Environment
System:
OS: macOS 12.5
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Binaries:
Node: 16.16.0 - /usr/local/opt/node@16/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 8.13.2 - /usr/local/bin/npm
npmPackages:
jest: ^28.1.3 => 28.1.3
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 18 (11 by maintainers)
@mildmojo
Did you try like this:
Thanks for repo. Easy to fix. Change your test file like this:
As you suspected – ESM evaluates
import
statements before looking at the code. So you have tomock
before importing. Same applies for for modules which have to load mocked modules (in this case it is themain.cjs
which loadsBrowserWindow
).This pattern worked with CJS, because
babel-jest
transformer is movingjest.mock
calls at the top of the file (above anyrequire
statement). Hoisting magic does not work with ESM, because any staticimport
will be always evaluated first. Solution: use dynamicimport()
.