test-mock-prefix
a module-scope mock variable without the `mock` prefix Jest hoisting needs
Deterministic checkblocking by defaultbasetests
The argument
Mocks
- Place mock declarations and
jest.mock()blocks after the imports, marked with a// Mocked Importsheader and// -------------------------separators between groups (mirror any existing test file's formatting). - Mock variables must be prefixed
mock— Jest hoistsjest.mock()calls to the top of the file, and onlymock-prefixed variables are accessible inside the factory. - Set mock return values inside the
setup()factory — never in abeforeEach. - Do NOT mock modules that only export plain constants — import the real module; mocking it blocks coverage and adds no isolation. Mock a constant module only if it has import-time side effects or the test needs a different value (prefer
jest.replacePropertyor injection). - Scope strategy: inline mocks for one file; a co-located
__mocks__/folder when multiple tests in the area share a mock;test/mocks/(withtest/fixtures/,test/utils/) for codebase-wide utilities.
The proof
failsubject.unit.test.ts
import { expect, describe, test, jest } from '@jest/globals';
const getProfile = jest.fn<() => string>();
describe('subject', () => {
test('reads the profile', () => {
getProfile.mockReturnValue('p.png');
expect(getProfile()).toBe('p.png');
});
});
passsubject.unit.test.ts
import { expect, describe, test, jest } from '@jest/globals';
const mockGetProfile = jest.fn<() => string>();
const setupProfile = () => {
const getGravatar = jest.fn<() => string>();
mockGetProfile.mockReturnValue('p.png');
getGravatar.mockReturnValue('g.png');
return { getGravatar };
};
describe('subject', () => {
test('reads the profile', () => {
const { getGravatar } = setupProfile();
expect(mockGetProfile() + getGravatar()).toBe('p.pngg.png');
});
});
Turn it down
Both lines go in your lightsout.config.json.
"standards-checks": { "test-mock-prefix": "advisory" }"standards-checks": { "test-mock-prefix": "off" }