Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest 27 errors with ReferenceError: setImmediate is not defined #8558

Open
ericwooley opened this issue Aug 3, 2021 · 34 comments
Open

Jest 27 errors with ReferenceError: setImmediate is not defined #8558

ericwooley opened this issue Aug 3, 2021 · 34 comments
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: jest topic: tests

Comments

@ericwooley
Copy link

ericwooley commented Aug 3, 2021

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.

@janpio
Copy link
Member

janpio commented Aug 4, 2021

While upgrading to 27.0.3

Version 27.0.3of what exactly?

setImmediate is a Node feature: https://nodejs.org/api/timers.html#timers_setimmediate_callback_args
What node version are you using?

@ericwooley
Copy link
Author

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

@ericwooley
Copy link
Author

ericwooley commented Aug 4, 2021

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 jestjs/jest#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.

@pantharshit00 pantharshit00 added the team/client Issue for team Client. label Aug 6, 2021
@Jolg42 Jolg42 changed the title Remove use of setImmediate Jest 27 errors with ReferenceError: setImmediate is not defined Aug 12, 2021
@erawk
Copy link

erawk commented Aug 31, 2021

@ericwooley @janpio I've seen this error as well. Downgrading from Jest 27.x to 26.6.3 solved the problem.

The error that was being thrown was:

    ReferenceError: setImmediate is not defined

      at Parser.destroy (node_modules/@prisma/client/runtime/index.js:27664:7)

And in the generated runtime client, the code that calls setImmediate looks like:

    destroy() {
      clearTimeout(this.timeout);
      this.timeout = null;
      this.unconsume();
      setImmediate((self) => self.close(), this);
    }

Downgrading Jest hid this error, likely due to Jest overriding setImmediate to muck around with timers internally.

Using jest.useFakeTimers() in jest.setup.ts hid the issue, but if we call prisma.$disconnect() to clean up, we see the issue again. Running jest.runAllTimers() in an afterAll callback after we call prisma.$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.

@TomSssM
Copy link

TomSssM commented Dec 6, 2021

Same problem here, using jest + ts-jest, had to downgrade jest and the related deps to major version 26:

{
  "@types/jest": "26.0.14",
  "jest": "26.6.3",
  "ts-jest": "26.5.6"
}

@ericwooley
Copy link
Author

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.

@davidmoshal
Copy link

Some problem, using Playwright

@TomSssM
Copy link

TomSssM commented Dec 18, 2021

By the way, if using Jest, make sure your env is set to node instead of jsdom because setImmediate doesn't exist in jsdom as it is Node-only feature

@davidmoshal
Copy link

@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?

@TomSssM
Copy link

TomSssM commented Dec 21, 2021

@davidmoshal my theory was that env jsdom supposes you to run client-side only code inside of it and client side code should not use setImmediate as it is a Node.js feature. When I changed my env to node (after accidentally setting it to jsdom) everything started working, when env is jsdom you don't have setImmediate 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).

@davidmoshal
Copy link

@TomSssM , you're missing the point.
I'm testing browsers, ie: I'm testing client side code, therefore I need Jsdom.
If I set it to 'node' then it complains about numerous things, eg: no window object, etc.
Take a look at Playwright: https://playwright.dev/
Maybe that will help you understand?

@TomSssM
Copy link

TomSssM commented Dec 21, 2021

@davidmoshal I already understood your point and I know that switching from jsdom to node is not an option for you, in my initial reply I simply wrote what helped me out so that others who come across this issue first check their env as it was the problem in my case. You have a more complicated case where you cannot switch to node from jsdom, in my case I should have switched to node in the first place as I was writing tests for the server (and for my client side code I have a separate jest config with env set to jsdom).

Unfortunately I don't know how to help you out, I would roll jest back to 26 and hope somebody does a fix in response to this issue. Yup, it is often difficult to migrate to a new major of some library, we have all been there

@davidmoshal
Copy link

Thanks

@roshkins
Copy link

When I put

/*
* @jest-environment node
*/

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.

@dtostes-meli
Copy link

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

module.exports = {
  ...
  setupFilesAfterEnv: [
    '<rootDir>/jest.env.js',
  ],
  ...
}

jest.env.js

global.setImmediate = jest.useRealTimers;

@silvenon
Copy link

silvenon commented Jan 20, 2022

@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 in jsdom was a mistake corrected in Jest 27.

@bengeorge
Copy link

@silvenon is probably right here.

I chose to replace setImmediate(foo) usages with setTimeout(foo, 0), and for our tests it was adequate.

@fatso83
Copy link

fatso83 commented Feb 15, 2022

If you are actually using setImmediate in your tests, but your test environment is actually jsdom, the cleanest approach is to simply import the dependency. Just add this at the top:

/**
 * @jest-environment jsdom
 */

import {setImmediate} from 'timers'

@jaimeagudo
Copy link

jaimeagudo commented Apr 19, 2022

I am afraid I don't see how this would have worked for anyone

global.setImmediate = jest.useRealTimers;

TLDR: What worked for me is

global.setImmediate = global.setImmediate || ((fn, ...args) => global.setTimeout(fn, 0, ...args));

For those interested https://nodejs.dev/learn/understanding-setimmediate

@fatso83
Copy link

fatso83 commented Apr 19, 2022

@jaimeagudo You are just replacing a missing setImmediate with a call to setTimeout. Did you try just importing the setImmediate timer?

@nabeelfarid
Copy link

nabeelfarid commented Apr 22, 2022

If you are actually using setImmediate in your tests, but your test environment is actually jsdom, the cleanest approach is to simply import the dependency. Just add this at the top:

/**
 * @jest-environment jsdom
 */

import {setImmediate} from 'timers'

The import statement does get rid of the error ' ReferenceError: setImmediate is not defined'
But when I try to test wether setImmediate has been processed , it doesn't seem to work. E.g. the following test fails

  import { setImmediate } from 'timers';

  jest.useFakeTimers('legacy');
  const m = jest.fn();
  setImmediate(m);
  jest.runAllImmediates();
  expect(m).toHaveBeenCalled();

how do you force setImmediate to process with Jest v27 ? The runAllImmediates() works in v26

@fatso83
Copy link

fatso83 commented Apr 22, 2022

@nabeelfarid My comment was just actually referring to fixing the issue about setImmediate not being defined in the test, not in any implementation code. Importing it will just bring it into the scope of the test and no implementation code will know about it and it will not be added to the global scope. Jest only stubs the bits in the global scope, so if you want Jest to do anything about global.setImmediate, you would need to bind it to global, AFAIK. As in global.setImmediate = setImmediate.

Still, I do not think your example makes much sense anyhow: you only test the effects of what is happening inside your test module. This does not prove anything about code imported from outside your test module. jsdom does not have setImmediate in Jest 27, so any implementation code relying on it should fail regardless.

P.S. I do not even know what Prisma is and just happened to see this from some other thread, so unsubscribing.

@tobilg
Copy link

tobilg commented May 17, 2022

jest.env.js

global.setImmediate = jest.useRealTimers;

If you're using TypeScript, the following worked for me:

global.setImmediate = jest.useRealTimers as unknown as typeof setImmediate;

@uroslates
Copy link

For me setting testEnvironment to node (testEnvironment: 'node',) within jest.config.ts solved the problem.

@regican
Copy link

regican commented Feb 7, 2023

Following @tobilg's solution, setting global.setImmediate = global.setTimeout; worked for me.

@kameshdhana
Copy link

/*
* @jest-environment node
*/

Such a banger workaround

@earonesty
Copy link

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 tests

global.setImmediate = jest.useRealTimers;

@Jolg42 Jolg42 added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. and removed bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. labels Jul 13, 2023
@jkomyno
Copy link
Contributor

jkomyno commented Aug 3, 2023

Some updates on this issue:

  • we were not able to reproduce this problem with jest@27.0.3 and ts-jest@27.0.3, using prisma@5.1.0
  • we were able to run integration tests with Prisma Client on Jest with testEnvironment: "node", using more recent versions (v29+)
  • we ran those tests on Node.js v16.17.1 and on Node.js v18.16.1. We did not try using Node.js v14.17.4, as it is no longer compatible with Prisma.

What is the most recent version of Prisma and Node.js where you people have detected this issue? Moreover, I see several proposed solutions above that seem to have been appreciated by the community (in particular, setting the testEnvironment: "node" configuration property for Jest. Would you thus consider this issue as fixed?

@robbporto
Copy link

This is still happening.

@janpio
Copy link
Member

janpio commented Sep 7, 2023

@robbporto Can you provide some more information on the versions and exactly what you are doing so we can reproduce this, please?

@millsp
Copy link
Member

millsp commented Nov 7, 2023

@jkomyno have you tried it with the jsdom jest environment as well?

@maximgeerinck
Copy link

global.setImmediate = jest.useRealTimers;

I am afraid I don't see how this would have worked for anyone

global.setImmediate = jest.useRealTimers;

TLDR: What worked for me is

global.setImmediate = global.setImmediate || ((fn, ...args) => global.setTimeout(fn, 0, ...args));

For those interested https://nodejs.dev/learn/understanding-setimmediate

This is the only correct solution for me. the other one (global.setImmediate = jest.useRealTimers;) gave me timeouts.

@fatehMohamed14
Copy link

fatehMohamed14 commented Nov 30, 2023

This is what worked for me (react typescript app), add it inside the test file, socketio was causing the error for me

    //@ts-ignore
    window.setImmediate = window.setTimeout

@panat54083
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: jest topic: tests
Projects
None yet
Development

No branches or pull requests