Does jest.retryTimes reset module state between retries, or are side-effect writes duplicated?
0 reputation · 17 Mar 2021, 23:23 UTC
0 reputation · 17 Mar 2021, 23:23 UTC
I am designing a test suite that uses jest.retryTimes(2) to tolerate occasional flakiness in integration tests that write to a shared test database and filesystem fixtures.
The documented behavior is clear that a failed test function is re-executed from the start, but it is unclear to me whether Jest resets the module registry or any other environment state between those retry attempts. My concern is that non-idempotent operations inside the test body — inserts, file appends, counter increments — would run once per attempt, silently duplicating writes and corrupting shared fixtures for later tests.
The configuration options resetModules, resetMocks, and clearMocks look relevant, but I cannot find documentation describing how they interact with retries specifically: whether they apply between retry attempts of the same test, or only between separate test files/cases.
So my questions are:
jest.retryTimes reset module state or mocks between retry attempts by default, or must this be configured explicitly?resetModules: true and clearMocks: true take effect between retries of the same test, and is this behavior stable across recent Jest versions?30275 reputation · 18 Mar 2021, 07:34 UTC
When a test is retried with jest.retryTimes(n), Jest **does not** automatically reset the module registry, the mock registry, or any global state. The same module instances are reused for every retry attempt, and mock call history is preserved across retries.
The global Jest configuration options resetModules, resetMocks, and clearMocks are applied only when Jest transitions between different test files or test suites. They are not invoked between retry attempts of the same test case.
const fs = require('fs');
const tmp = require('tmp-promise');
jest.retryTimes(2);
test('duplicate write on retry', async () => {
const { path } = await tmp.file();
fs.appendFileSync(path, 'attempt\n');
const content = fs.readFileSync(path, 'utf8');
expect(content.split('\n')).toHaveLength(2); // will fail on first run
});
jest.mock('./service', () => ({ doWork: jest.fn() }));
jest.retryTimes(2);
test('mock persists across retries', () => {
const { doWork } = require('./service');
doWork();
expect(doWork).toHaveBeenCalledTimes(1); // will be 2 after retry
});
beforeAll and clean up in afterAll. The hooks run once per test file, so retries will not repeat them.jest.resetModules() and clearing mocks in a beforeEach hook. Note that this adds overhead and may not be sufficient if the side effect is external (e.g., a database).Across Jest 27 through 29, the described behavior is consistent. Future releases may introduce changes, but no current version guarantees automatic reset between retries.
Jest does not provide a built‑in hook for resetting state between retries. The only reliable approach is to refactor the test or add manual cleanup logic as described above.
If you observe unexpected duplication even after following these patterns, check whether the side effect is performed by a third‑party module that caches state internally. In that case, you may need to mock or stub that module explicitly for each retry.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.