jest
jest copied to clipboard
resetAllMocks between describe blocks is counter-intuitive
🐛 Bug Report
When you run jest.resetAllMocks()
in one describe
block, it will also reset mocks defined in other describe
blocks. This struck me as counter-intuitive, even if after reading the docs carefully it seems to be how it is documented.
To Reproduce
Steps to reproduce the behavior: Run the following test file:
const topLevel = jest.fn();
describe("first block", () => {
const one = jest.fn();
const two = jest.fn();
const three = jest.fn();
afterEach(() => jest.resetAllMocks());
// Assume the tests in this block each configure the mocks with some values / implementation
test("first block test", () => {
expect([topLevel, one, two, three]).toBeDefined();
});
});
describe("second block", () => {
const local = jest.fn(() => 123);
test("second block test", () => {
expect(local()).toBe(123); // Fails! Expected: 123 / Received: undefined
});
});
Expected behavior
The intuitive behavior, IMO, would be for the second block test to succeed. One expects that what happens in one describe block does not affect other describe blocks, except via global state.
I think I understand what actually happens: Jest first runs both describe
blocks, and it gathers tests and before/after blocks. Then it starts running each test (with any appropriate before/after blocks). This means that the local
mock is defined (and captured by the second block tests) before any test is run. Then Jest runs the first test; its after block calls resetAllMocks
, which also resets the local
mock, removing its implementation. Then Jest runs the second test, but local
no longer has an implementation, so it fails.
I think the intuitive behavior would be that resetAllMocks
(and other similar methods such as clearAllMocks
), when called from inside a describe
block, would only affect (1) mocks defined in that describe
block and (2) mocks defined in parent describe
blocks and/or at global scope.
(I mean, probably the correct thing would be to cleared/reset mocks after every test by default, or even forcefully, but that I understand might take some time.)
Also, if mocks are cleared/reset after each test by default, jest.fn
, spy
and similar functions should not accept an implementation or other mock configuration when called directly inside a describe
block. Mocking values and implementations should only be allowed inside tests and before/after blocks, anything else is a clear error, since they would be lost after each test.
Link to repl or repo (highly encouraged)
https://repl.it/@BogdanButnaru/jest-playground
envinfo
npx: installed 1 in 2.3s
System:
OS: Windows 10 10.0.18363
CPU: (4) x64 Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz
Binaries:
Node: 14.7.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.4 - ~\AppData\Roaming\npm\yarn.CMD
npm: 6.14.11 - C:\Program Files\nodejs\npm.CMD