Skip to content

Jest has changed its timer implementation causing waitFor() not to work properly #612

@jasonwilliams

Description

@jasonwilliams
  • @testing-library/dom version: 7.5.2
  • Testing Framework and version: 10.0.4
  • DOM Environment: Jest
    Jest version: 25.1.0
    Node v12

We had some code which uses fakeTimers, I noticed it was screwing up waitFor().
So i needed to run jest.useRealTimers() just before calling waitFor() to fix the issue.

This shouldn't be needed, as testing-library tries to safe-guard against fakeTimer use, you can see here:
https://github.com/testing-library/dom-testing-library/blob/master/src/helpers.js#L5-L8

However, i noticed this line will always return undefined regardless of whether you have fakeTimers on or not. This is due to the fact that globalObj.setTimeout._isMockFunction is always undefined.
My guess is Jest used to mock setTimeout using its own utilities and this property once existed, but now Jest uses @Sinon/MockTimers where this property is not added.

When did this happen?

Looks like the change happened in Jest v26
https://github.com/facebook/jest/releases/tag/v26.0.0

there were also implementation changes in v25.1
https://github.com/facebook/jest/releases?after=v25.5.1

_isMockFunction is added here:
https://github.com/facebook/jest/blob/master/packages/jest-fake-timers/src/legacyFakeTimers.ts#L370

It was swapped out in v25, plan here:
jestjs/jest#7776 (comment)

Solution

The fix is to find another way to see if the timers are being mocked or not, as the current heuristics don't work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is neededreleased

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions