Jest / Vitest Cheatsheet
Complete Jest & Vitest reference. Hit Ctrl+P to print.
Setup & CLI
npm install --save-dev jestInstall Jest as a dev dependencynpm install --save-dev vitestInstall Vitest as a dev dependencynpx jestRun all tests with Jestnpx vitest runRun all tests once with Vitest (no watch)npx jest --watchRun Jest in watch mode (re-runs on file change)npx vitestRun Vitest in watch mode (default)npx jest --coverageRun Jest with code coverage reportnpx vitest --coverageRun Vitest with code coverage reportnpx jest path/to/fileRun Jest on a specific file or patternnpx vitest path/to/fileRun Vitest on a specific file or patternnpx jest -t "test name"Run only tests matching the given name (Jest)npx vitest -t "test name"Run only tests matching the given name (Vitest)npx jest --verboseShow individual test results with descriptionsnpx vitest --reporter=verboseShow verbose test output in Vitestnpx vitest --uiOpen Vitest browser UI dashboardnpx jest --bailStop after the first test failurenpx jest --clearCacheClear Jest cache directoryjest.config.js / vitest.config.tsConfiguration file for test runner optionsTest Structure
test('name', fn)Define a test caseit('name', fn)Alias for test() - same behaviourtest.only('name', fn)Run only this test in the file (also it.only)test.skip('name', fn)Skip this test (also it.skip)test.todo('name')Placeholder for a test to be written laterdescribe('group', fn)Group related tests into a suitedescribe.only(...)Run only this describe blockdescribe.skip(...)Skip this describe blockdescribe.each(table)(name, fn)Run a describe block for each row in a data tabletest.each(table)(name, fn)Run a test for each row in a data tabletest.each([[1,2],[3,4]])('%i + %i', (a, b) => {})Data-driven test with inline table and printf-style nametest.concurrent('name', fn)Run test in parallel with other concurrent tests (Jest 27+ and Vitest)test.fails('name', fn)Mark test as expected to fail - passes if any assertion fails (Vitest)Lifecycle Hooks
beforeAll(fn)Run once before all tests in current scopeafterAll(fn)Run once after all tests in current scopebeforeEach(fn)Run before each individual testafterEach(fn)Run after each individual testbeforeAll / afterAll inside describeHook scoped to that describe block onlybeforeEach(async () => { ... })Async hook - await setup logicbeforeAll(() => { return db.connect() })Return a promise to make Jest/Vitest wait for itNested describe hooks run outside-inOuter beforeEach runs before inner beforeEachMatchers - Equality & Truthiness
expect(val).toBe(x)Strict equality (===) - for primitivesexpect(val).toEqual(x)Deep equality - recursively checks object/array structureexpect(val).toStrictEqual(x)Deep equal + checks object types (no undefined properties)expect(val).toBeNull()Value is nullexpect(val).toBeUndefined()Value is undefinedexpect(val).toBeDefined()Value is not undefinedexpect(val).toBeTruthy()Value is truthyexpect(val).toBeFalsy()Value is falsyexpect(val).toBeNaN()Value is NaNexpect(val).not.toBe(x)Negate any matcher with .notMatchers - Numbers & Strings
expect(val).toBeGreaterThan(n)Value is greater than nexpect(val).toBeGreaterThanOrEqual(n)Value is greater than or equal to nexpect(val).toBeLessThan(n)Value is less than nexpect(val).toBeLessThanOrEqual(n)Value is less than or equal to nexpect(val).toBeCloseTo(n, digits)Float comparison with decimal precision (avoids rounding issues)expect(str).toMatch(/regex/)String matches a regular expressionexpect(str).toMatch('substring')String contains substringexpect(val).toContain('substring')String contains substring, or array contains itemexpect(val).toHaveLength(n)String or array has length nexpect(val).toMatchObject({ key: val })Object contains at least these key/value pairs (partial match)expect(val).toHaveProperty('key')Object has the given propertyexpect(val).toHaveProperty('key', val)Object has the given property with specific valueexpect(val).toHaveProperty('a.b.c')Check nested property using dot-notation pathMatchers - Arrays, Objects & Errors
expect(arr).toContain(item)Array contains the exact item (===)expect(arr).toContainEqual({ key: val })Array contains an item deeply equal to the given objectexpect(arr).toEqual(expect.arrayContaining([1,2]))Array contains at least these items (order-independent)expect(obj).toEqual(expect.objectContaining({ key: val }))Object has at least these propertiesexpect(str).toEqual(expect.stringContaining('str'))String contains given substring (as asymmetric matcher)expect(str).toEqual(expect.stringMatching(/regex/))String matches regex (as asymmetric matcher)expect(val).toEqual(expect.any(String))Value is an instance of the given constructorexpect(val).toEqual(expect.anything())Matches anything except null/undefinedexpect(() => fn()).toThrow()Function throws any error - must wrap in arrow fnexpect(() => fn()).toThrow('message')Function throws with matching messageexpect(() => fn()).toThrow(ErrorClass)Function throws an instance of given error classexpect(() => fn()).toThrow(/regex/)Function throws with message matching regexAsync Testing
test('name', async () => { ... })Async test - use await insideawait expect(promise).resolves.toBe(val)Assert a promise resolves with given valueawait expect(promise).rejects.toThrow('error')Assert a promise rejects with given errorreturn expect(promise).resolves.toBe(val)Return the assertion promise so Jest/Vitest waitsexpect.assertions(2)Verify exactly N assertions ran - essential for async testsexpect.hasAssertions()Verify at least one assertion rantest('name', done => { ... done() })Callback-style async - call done() when finisheddone(err)Call done with error to fail the testvi.useFakeTimers() / jest.useFakeTimers()Replace real timers with fake controllable timersvi.runAllTimers() / jest.runAllTimers()Run all pending timers synchronouslyvi.advanceTimersByTime(1000) / jest.advanceTimersByTime(1000)Advance all timers by msvi.useRealTimers()Restore real timer implementationMocking
jest.fn() / vi.fn()Create a mock function with no implementationvi.fn(() => 'return value')Create a mock function with a default implementationmockFn.mockReturnValue(val)Always return val when mock is calledmockFn.mockReturnValueOnce(val)Return val only on the next call, then revertmockFn.mockResolvedValue(val)Mock async function always resolving to valmockFn.mockResolvedValueOnce(val)Mock async function resolving to val on next call onlymockFn.mockRejectedValue(err)Mock async function always rejecting with errmockFn.mockRejectedValueOnce(err)Reject with error once, then use default implementationmockFn.mockImplementation(fn)Replace mock implementation with given functionmockFn.mockImplementationOnce(fn)Use given implementation for next call onlymockFn.mockReset()Reset call history AND implementationmockFn.mockClear()Reset call history only (keep implementation)mockFn.mockRestore()Restore original implementation - only works for spiesjest.spyOn(obj, 'method') / vi.spyOn(obj, 'method')Spy on an existing method without replacing itvi.spyOn(obj, 'method').mockReturnValue(val)Spy and override return valuejest.mock('./module') / vi.mock('./module')Auto-mock all exports of a modulejest.mock('./module', () => ({ fn: jest.fn() }))Manual mock factory - specify exact mock exports (Jest)vi.mock('./module', () => ({ fn: vi.fn() }))Manual mock factory - specify exact mock exports (Vitest)jest.unmock('./module') / vi.unmock('./module')Unmock a previously mocked modulejest.resetAllMocks() / vi.resetAllMocks()Reset all mock implementations and call historyjest.clearAllMocks() / vi.clearAllMocks()Clear call history on all mocksMock Assertions
expect(mockFn).toHaveBeenCalled()Mock was called at least onceexpect(mockFn).not.toHaveBeenCalled()Mock was never calledexpect(mockFn).toHaveBeenCalledTimes(n)Mock was called exactly n timesexpect(mockFn).toHaveBeenCalledWith(arg1, arg2)Mock was called with specific arguments at least onceexpect(mockFn).toHaveBeenLastCalledWith(arg)Last call to mock had these argumentsexpect(mockFn).toHaveBeenNthCalledWith(n, arg)nth call to mock had these arguments (1-indexed)expect(mockFn).toHaveReturnedWith(val)Mock returned given value at least oncemockFn.mock.callsArray of argument arrays for each callmockFn.mock.calls[0]Arguments of the first callmockFn.mock.resultsArray of {type, value} for each call returnmockFn.mock.instancesArray of this-context for each call (new usage)mockFn.mock.calls.lengthTotal number of times the mock was calledmockFn.mock.results[0].valueReturn value of the first callSnapshot Testing
expect(val).toMatchSnapshot()Save snapshot on first run; assert equality on subsequent runsexpect(val).toMatchInlineSnapshot()Inline snapshot stored directly in test fileexpect(val).toMatchSnapshot('name')Named snapshot - useful when multiple snapshots per testnpx jest --updateSnapshot / npx vitest --update-snapshots / -uUpdate failing snapshotsexpect(val).toMatchFileSnapshot('./path.txt')Snapshot stored in a specific file (Vitest only)jest.addSnapshotSerializer(serializer)Register a custom snapshot serializerSnapshots stored in __snapshots__/Auto-created directory next to test filesDelete .snap file to regenerateRemove the snapshot file to recreate from scratchModule Mocking Patterns
__mocks__/ directoryAuto-mock: place mock next to module; Jest uses it automatically with jest.mock()vi.mock('./mod', () => ({ default: vi.fn() }))Mock ES module default exportvi.mock('./mod', () => ({ namedFn: vi.fn() }))Mock named exportvi.mock('./mod', async (importOriginal) => ({ ...await importOriginal(), fn: vi.fn() }))Partial mock - spread original and override specific exports (Vitest)vi.importMock('./mod')Dynamically import an auto-mocked module (Vitest)vi.importActual('./mod')Dynamically import the real (unmocked) module (Vitest)jest.requireActual('./mod')Import real module inside a mock factory (Jest)vi.stubEnv('NODE_ENV', 'production')Override an environment variable for the test (Vitest)vi.restoreAllMocks()Restore all spied originals and implementations (Vitest)vi.mock called at top of filevi.mock is hoisted - call order in file does not matterCoverage
npx jest --coverageGenerate code coverage report with Jestnpx vitest --coverageGenerate code coverage report with VitestcollectCoverage: trueAlways collect coverage in jest.config.jscoverageThreshold: { global: { lines: 80 } }Fail if coverage falls below threshold (jest.config.js)coverageProvider: 'v8'Use V8 for faster coverage (alternative to default 'babel')collectCoverageFrom: ['src/**/*.js']Specify which files to include in coveragecoverageReporters: ['text', 'html', 'lcov']Coverage output formats (Jest config key is coverageReporters, Vitest: coverage.reporter)coverage/index.htmlView detailed HTML coverage report in browser--coverage.include / --coverage.excludeFilter files included in coverage (Vitest CLI)/* istanbul ignore next */Exclude next line from Istanbul coverage/* c8 ignore next */Exclude next line from V8 coverage