prisma: Jest 27 errors with `ReferenceError: setImmediate is not defined`
Problem
While upgrading to 27.0.3 of jest, I have failing integration tests because
● Test suite failed to run
ReferenceError: setImmediate is not defined
at Parser.destroy (../../../node_modules/@prisma/client/runtime/index.js:25498:7)
at detachSocket (../../../node_modules/@prisma/client/runtime/index.js:25536:21)
at Socket.onSocketClose (../../../node_modules/@prisma/client/runtime/index.js:25545:5)
Suggested solution
Because setImmediate is a non-standard API in the first place, and only officially supported by ie10, prisma should remove references to it.
Sorry if this is the wrong report time, I was split between a feature request and a bug.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 1
- Comments: 34 (4 by maintainers)
Commits related to this issue
- wip - fix error with setImmediate in jest 27 https://github.com/prisma/prisma/issues/8558#issuecomment-1021172188 — committed to pass-culture/pass-culture-app-native by marineshaw a year ago
I am afraid I don’t see how this would have worked for anyone
TLDR: What worked for me is
For those interested https://nodejs.dev/learn/understanding-setimmediate
If you are actually using
setImmediate
in your tests, but your test environment is actuallyjsdom
, the cleanest approach is to simply import the dependency. Just add this at the top:I had the same issue after updating to
jest v27
. For those who could not solve with any of the previous responses (like me). After some research I’ve solved with:jest.config.js
jest.env.js
When I put
above my import statements it fixed it for me, since it was a dependency that was using setImmediate. It didn’t work when I put it below the statements.
By the way, if using Jest, make sure your env is set to
node
instead ofjsdom
becausesetImmediate
doesn’t exist injsdom
as it is Node-only featureIf you’re using TypeScript, the following worked for me:
For me setting testEnvironment to
node
(testEnvironment: 'node',
) withinjest.config.ts
solved the problem.@silvenon is probably right here.
I chose to replace
setImmediate(foo)
usages withsetTimeout(foo, 0)
, and for our tests it was adequate.For anyone else getting here from google or whatever, there are lots of changes regarding setImmediate in the jest changelog for 27 https://github.com/facebook/jest/blob/master/CHANGELOG.md
I’m still investigating, but I suspect https://github.com/facebook/jest/pull/11222 might have to do with it.
obviously make sure your test env is set to node. (ours is, and we still get the problem 🤷♂️ ). I’ll update this issue when I figure it out.
EDIT: Just an update as to my investigation on this. I never figured it out, I think updating to an even newer jest version than 27.0.3 may have fixed it, but I don’t have access to the codebase where this was a problem anymore. So I won’t be able to investigate this.
Following @tobilg’s solution, setting
global.setImmediate = global.setTimeout;
worked for me.@davidmoshal what kind of code are you testing that needs both DOM and Node environment to exist? Maybe you can work around the problem somehow, so if you post the code someone might be able to help.
The way I see it, the fact that Jest 26 supported
setImmediate
injsdom
was a mistake corrected in Jest 27.@davidmoshal my theory was that env
jsdom
supposes you to run client-side only code inside of it and client side code should not usesetImmediate
as it is a Node.js feature. When I changed my env tonode
(after accidentally setting it tojsdom
) everything started working, when env isjsdom
you don’t havesetImmediate
in the global object. I guess the reasoning behind it is what I wrote above (client side code should not rely on Node.js specific features). But hey, I might be wrong, I was simply debugging why my jest tests were failing (alas the bug was caused by my lack of attention).note:
this worked for me, and the bug is in
react-native-animated
. it detects your environment as “node” even when you’re running jsdom testsglobal.setImmediate = jest.useRealTimers;
Hi @janpio
Sorry, 27.0.3 of jest
14.17.4
I didn’t realize it was built into node, I’ll have to investigate why jest 27 is breaking that
I didn’t use setimmediate in my code but in the error, it came from node_modules. I fixed this by
install
npm i setimmediate @types/setimmediate
in jest.setup.ts
import 'setimmediate';
Ref. https://stackoverflow.com/questions/74902478/why-referenceerror-setimmediate-is-not-defined-when-im-not-using-it-at-all
This is still happening.
@TomSssM: that’s a very strange response. I need jsdom because, as stated above, I’m using Playwright (a browser automation framework).
Jest 26 worked fine (as you noticed), but Jest 27 fails, even if you set the test environment to jsdom, and add the relevant dependencies.
It’s curious to me that Jest 26 works (with the default jsdom environment), yet Jest 27 fails when you explicitly set the test environment to jsdom.
I wonder what has changed in the Jest 27 jsdom implementation?
Such a banger workaround
Just an update as to my investigation on this. I never figured it out, I think updating to an even newer jest version than 27.0.3 may have fixed it, but I don’t have access to the codebase where this was a problem anymore. So I won’t be able to investigate this.
@ericwooley @janpio I’ve seen this error as well. Downgrading from Jest
27.x
to26.6.3
solved the problem.The error that was being thrown was:
And in the generated runtime client, the code that calls
setImmediate
looks like:Downgrading Jest hid this error, likely due to Jest overriding
setImmediate
to muck around with timers internally.Using
jest.useFakeTimers()
injest.setup.ts
hid the issue, but if we callprisma.$disconnect()
to clean up, we see the issue again. Runningjest.runAllTimers()
in anafterAll
callback after we callprisma.$disconnect()
did not help either.This is likely a Jest issue, but not sure if there’s any advice on how to avoid triggering this.