patterntypescriptnoneMajor
Test Isolation: Preventing State Leaks Between Tests
Viewed 0 times
test isolationstate leakclearAllMockscleanupafterEachbeforeEach
Error Messages
Problem
Tests pass individually but fail when run together. One test's side effects (global state, mocks, timers, DOM nodes) contaminate subsequent tests.
Solution
Reset all shared state after each test using framework hooks.
// Reset mocks after each test
afterEach(() => {
jest.clearAllMocks(); // Clear calls and return values
// jest.resetAllMocks() — also removes implementations
// jest.restoreAllMocks() — restores spied-on originals
});
// Reset timers
beforeEach(() => { jest.useFakeTimers(); });
afterEach(() => { jest.useRealTimers(); });
// React: automatic DOM cleanup
import '@testing-library/react'; // auto-cleanup on import
// Or manually:
import { cleanup } from '@testing-library/react';
afterEach(cleanup);
// Database: use transactions rolled back after each test
beforeEach(async () => {
await db.beginTransaction();
});
afterEach(async () => {
await db.rollbackTransaction();
});
// Module-level singletons: reset in beforeEach
beforeEach(() => {
jest.isolateModules(() => {
// Fresh module imports for each test
});
});Why
Test order should be irrelevant. Shared mutable state (module-level variables, global fetch mocks, DOM nodes) persist across tests unless explicitly cleaned up.
Gotchas
- clearAllMocks() does not restore original implementations of spies — use restoreAllMocks() for that.
- In-memory databases (like better-sqlite3) need explicit clearing between tests.
- jest.resetModules() clears the module registry but does not re-run setup files.
Revisions (0)
No revisions yet.