-
-
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
[Bug]: jest.restoreAllMocks()
clobbers legacy fake timers since 29.4.3
#14390
Comments
@mrazauskas any immediate ideas? |
First though to check if time is faked (and that legacy implementation was used) and if so to call jest/packages/jest-runtime/src/index.ts Lines 1334 to 1336 in 0fd5b1c
Fake timers will get installed, but is that enough? These will be not the same instances of mock functions. Second thought from here: beforeEach(() => {
jest.restoreAllMocks();
jest.useFakeTimers({ legacyFakeTimers: true });
}); By the way, |
Thanks for the prompt response folks!
This is a fair point, but as you say, in those cases the "test fails with both versions of Jest". The "bug" here isn't so much that 29.4.3 behaves in a certain way, it's that it behaves differently from 29.4.2. In our case that's breaking a few dozen test suites and blocks upgrading within v29. Interestingly, it looks like jest/e2e/fake-timers-legacy/reset-all-mocks/__tests__/resetAllMocks.test.js Lines 10 to 16 in 0fd5b1c
resetAllMocks() from interfering with useFakeTimers() , but the test seems to omit actually calling resetAllMocks() . Maybe resetAllMocks() used to play nicely with useFakeTimers , but stopped working in a previous version?
Explicitly reinstalling timers after restoring mocks would work I think, but it's messy when timers are otherwise configured at the global/project level, and would make the migration to modern timers more difficult. I'd rather test authors not have to be worrying about the implementation details of timers. I know 29.4.3 is a few versions ago, but IMO a patch restoring previous behaviour and holding breaking changes until v30 would be worth considering here.
I wish we could get to that point 😅. We'd love to. Unfortunately, that's a pretty huge migration effort I was hoping not to have to think about for a minor bump. |
Thanks for pointing to this test suite. Note that it has a second test with these lines (legacy timers are used, because of jest/e2e/fake-timers-legacy/reset-all-mocks/__tests__/resetAllMocks.test.js Lines 19 to 20 in 0fd5b1c
File history is somewhat broken on GitHub. The test file was added in 2016 and got just few cosmetic changes (see #2109). This answers my question how
Hm.. Isn’t it that we could complain about any bug fix in similar way? The change we are talking about comes from #13867. Looking at the PR, you can see that this was just a tiny bug fix. I understand that the change is painful and that it is rather unfortunate to publish it as a minor release. All I could do is to spend time trying to explain how Jest got better after this change (see #13925). Hope this helps. |
Thanks for linking that context. It may well be that new behaviour is better designed, more consistent, etc - I’m not disagreeing with the change in principle - but as it was an apparently unintentional regression (breaks tests that previously passed), shouldn’t we follow semver, revert it and hold it back until v30? To put it directly, would you accept a PR that reverted the behaviour change, or is this effectively “wontfix”? |
I'm happy to land a revert and then revert the revert for v30 |
@robhogan This can be closed, right? |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Version
29.4.3
Steps to reproduce
git clone https://github.com/robhogan/jest-restore-mocks-bug
npm --prefix jest-29-4-2 test
passesnpm --prefix jest-29-4-3 test
failsExpected behavior
Tests that pass in 29.4.2 should pass in 29.4.3
Actual behavior
Test fails in 29.4.3
Additional context
I imagine this has a lot to do with the various changes to
restoreAllMocks
coupled with the fact that legacy timers are Jest mock based. CallinguseFakeTimers({ legacyFakeTimers: true })
afterjest.restoreAllMocks()
fixes the test again.I'm still looking into root-causing and fixing this but thought I'd share a repro as soon as I had one.
Environment
The text was updated successfully, but these errors were encountered: