-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
doc : jest fake timers : expect on setTimeout not working #11713
Comments
if you are using jest 27, it uses modern timers now by default |
I feel that the timer function used is an implementation detail, and that you would get more robust tests by instead looking at what you expect to happen once the task runs. Instead of checking if And similarly, if you need to verify that callbacks are scheduled with a particular time or interval, it would make sense to use |
Since this issue is tagged with "needs repro", here is a repro. I copied the example from the docs exactly, and setTimeout is not mocked. When I use legacy timers, the documented example works as expected. This suggests that the documentation demonstrates the legacy timers, not the modern timers. That document was last updated 8 months ago, and the commit history doesn't seem to suggest that the document was changed since the migration to modern timers. I can't actually find a document on the jest site for modern timers. Hopefully this reflects my own inability to find the right search terms, rather than that jest has migrated to an undocumented timer mock API? |
No, you are right; the current documentation is for the legacy timers and is outdated. I'm working on a new one 👍 |
How is one supposed to solve this issue? My tests start to fail as described in the inital report (i.e. I get a "received value must be a mock or spy function" error when invoking Adding
I’m using |
If you are using Jest 27 with its new default timer implementation, the current documentation is - as mentioned above - outdated. I have a draft for updated documentation in progress @ #11731. Perhaps the FAQ answer I added there could be of help? I would try to think about why you are trying to assert against |
That does explain the situation very well, thank you.
The specifics of my case make this undesirable (at least in my opinion). I’m updating a very small polling function that’s published as an npm package. Changing the code so that I’m able to pass a function as the Now in truth, the assertions looking at Side note: Specifically what I’d like to still be able to do is assess whether certain calls happened in an expected order. I don’t much care about the exact processor time that elapses but rather the information that events A, B, and C happened before event D. |
I went by all the reports about it not working and thought that perhaps it was sacrificed for the fact that relying on an external library greatly simplifies things for Jest. But actually, I was partially wrong and should have tested it more thoroughly. After you have enabled the fake timers you can spy on the global: jest.spyOn(global, 'setTimeout'); That said; I do still stand by my comment on it most often being more favourable not to do so.
When you use the modern fake timers, "processor time" should not play into the millisecond timing of when a given task can be expected to run though, because time is entirely faked. So with for example I would also think that tasks under fake timers would run in the natural order they are scheduled in. So if you want to ignore the exact timing... and only care about the order... then perhaps you can use |
Oh, and @kleinfreund, I almost forgot; there's also |
Ah, interesting. I had tried both:
I do agree. |
🙌
|
I’m experiencing a very strange return of this issue in the same project as before. I’ve made changes to my TypeScript source code (effectively adding 2
The underlying error is once more “ReferenceError: setTimeout is not defined”. The tests don’t run at all. The Reproduction steps:
|
I confirm that I also get
Test A passes, but code executed by Test B fails, @sigveio , not testing
|
This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
Is the documentation still out of date? Would be a shame to let this issue be closed without updating the docs. |
I also encountered the beforeAll(() => {
jest.useFakeTimers();
jest.spyOn(global, 'setTimeout');
});
afterAll(() => {
jest.useRealTimers();
}); causes my afterAll(() => server.close()); to fail with error I fixed this for now by just removing the Any ideas on how to debug this? BTW, the line in export function nextTick(callback: () => void) {
setTimeout(callback, 0) // <-- THIS
}
export function nextTickAsync(callback: () => void) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(callback())
}, 0)
})
} |
OK, it seems that the error above was caused by msw - more specifically msw versions >= 0.42.0. I'll post an issue to msw repo. |
What is the status of this issue? In my case, due to the timeouts being messed, I am having issues on the CI pipeline in github actions. Locally, everything looks fine, but in GA it seems that is not waiting enough for components to be rendered. |
I just found at that using jest.useFakeTimers() doesn't work at all if the calls to timer functions are imported instead of using globalThis. I had to remove import { setInterval, clearInterval } from 'node:timers'; to get the tests to pass. |
In my case ([email protected]), I found that it was the Repro: describe('main', () => {
describe('1', () => {
beforeAll(() => {
jest.useFakeTimers()
})
afterAll(() => {
jest.useRealTimers()
})
it('does at least one test', () => {})
})
describe('2', () => {
it('does another test', () => {
unitUnderTest.myMethod()
expect(setTimeout).toHaveBeenCalled()
// ^ ReferenceError: setTimeout is not defined
})
})
}) I found that simply commenting out the If I were to guess, something about jest.config.ts
|
🐛 Bug Report
In https://jestjs.io/fr/docs/timer-mocks, we can see that we can assert that setTimeout has been called once :
expect(setTimeout).toHaveBeenCalledTimes(1);
However, if you do this in a test, jest will complain :
I think the documentation should be fixed to explain how we can do ...
The text was updated successfully, but these errors were encountered: