Cheatsheets / Jest / Vitest

Jest / Vitest Cheatsheet

Complete Jest & Vitest reference. Hit Ctrl+P to print.

Setup & CLI

npm install --save-dev jestInstall Jest as a dev dependency
npm install --save-dev vitestInstall Vitest as a dev dependency
npx jestRun all tests with Jest
npx 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 report
npx vitest --coverageRun Vitest with code coverage report
npx jest path/to/fileRun Jest on a specific file or pattern
npx vitest path/to/fileRun Vitest on a specific file or pattern
npx 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 descriptions
npx vitest --reporter=verboseShow verbose test output in Vitest
npx vitest --uiOpen Vitest browser UI dashboard
npx jest --bailStop after the first test failure
npx jest --clearCacheClear Jest cache directory
jest.config.js / vitest.config.tsConfiguration file for test runner options

Test Structure

test('name', fn)Define a test case
it('name', fn)Alias for test() - same behaviour
test.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 later
describe('group', fn)Group related tests into a suite
describe.only(...)Run only this describe block
describe.skip(...)Skip this describe block
describe.each(table)(name, fn)Run a describe block for each row in a data table
test.each(table)(name, fn)Run a test for each row in a data table
test.each([[1,2],[3,4]])('%i + %i', (a, b) => {})Data-driven test with inline table and printf-style name
test.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 scope
afterAll(fn)Run once after all tests in current scope
beforeEach(fn)Run before each individual test
afterEach(fn)Run after each individual test
beforeAll / afterAll inside describeHook scoped to that describe block only
beforeEach(async () => { ... })Async hook - await setup logic
beforeAll(() => { return db.connect() })Return a promise to make Jest/Vitest wait for it
Nested describe hooks run outside-inOuter beforeEach runs before inner beforeEach

Matchers - Equality & Truthiness

expect(val).toBe(x)Strict equality (===) - for primitives
expect(val).toEqual(x)Deep equality - recursively checks object/array structure
expect(val).toStrictEqual(x)Deep equal + checks object types (no undefined properties)
expect(val).toBeNull()Value is null
expect(val).toBeUndefined()Value is undefined
expect(val).toBeDefined()Value is not undefined
expect(val).toBeTruthy()Value is truthy
expect(val).toBeFalsy()Value is falsy
expect(val).toBeNaN()Value is NaN
expect(val).not.toBe(x)Negate any matcher with .not

Matchers - Numbers & Strings

expect(val).toBeGreaterThan(n)Value is greater than n
expect(val).toBeGreaterThanOrEqual(n)Value is greater than or equal to n
expect(val).toBeLessThan(n)Value is less than n
expect(val).toBeLessThanOrEqual(n)Value is less than or equal to n
expect(val).toBeCloseTo(n, digits)Float comparison with decimal precision (avoids rounding issues)
expect(str).toMatch(/regex/)String matches a regular expression
expect(str).toMatch('substring')String contains substring
expect(val).toContain('substring')String contains substring, or array contains item
expect(val).toHaveLength(n)String or array has length n
expect(val).toMatchObject({ key: val })Object contains at least these key/value pairs (partial match)
expect(val).toHaveProperty('key')Object has the given property
expect(val).toHaveProperty('key', val)Object has the given property with specific value
expect(val).toHaveProperty('a.b.c')Check nested property using dot-notation path

Matchers - 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 object
expect(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 properties
expect(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 constructor
expect(val).toEqual(expect.anything())Matches anything except null/undefined
expect(() => fn()).toThrow()Function throws any error - must wrap in arrow fn
expect(() => fn()).toThrow('message')Function throws with matching message
expect(() => fn()).toThrow(ErrorClass)Function throws an instance of given error class
expect(() => fn()).toThrow(/regex/)Function throws with message matching regex

Async Testing

test('name', async () => { ... })Async test - use await inside
await expect(promise).resolves.toBe(val)Assert a promise resolves with given value
await expect(promise).rejects.toThrow('error')Assert a promise rejects with given error
return expect(promise).resolves.toBe(val)Return the assertion promise so Jest/Vitest waits
expect.assertions(2)Verify exactly N assertions ran - essential for async tests
expect.hasAssertions()Verify at least one assertion ran
test('name', done => { ... done() })Callback-style async - call done() when finished
done(err)Call done with error to fail the test
vi.useFakeTimers() / jest.useFakeTimers()Replace real timers with fake controllable timers
vi.runAllTimers() / jest.runAllTimers()Run all pending timers synchronously
vi.advanceTimersByTime(1000) / jest.advanceTimersByTime(1000)Advance all timers by ms
vi.useRealTimers()Restore real timer implementation

Mocking

jest.fn() / vi.fn()Create a mock function with no implementation
vi.fn(() => 'return value')Create a mock function with a default implementation
mockFn.mockReturnValue(val)Always return val when mock is called
mockFn.mockReturnValueOnce(val)Return val only on the next call, then revert
mockFn.mockResolvedValue(val)Mock async function always resolving to val
mockFn.mockResolvedValueOnce(val)Mock async function resolving to val on next call only
mockFn.mockRejectedValue(err)Mock async function always rejecting with err
mockFn.mockRejectedValueOnce(err)Reject with error once, then use default implementation
mockFn.mockImplementation(fn)Replace mock implementation with given function
mockFn.mockImplementationOnce(fn)Use given implementation for next call only
mockFn.mockReset()Reset call history AND implementation
mockFn.mockClear()Reset call history only (keep implementation)
mockFn.mockRestore()Restore original implementation - only works for spies
jest.spyOn(obj, 'method') / vi.spyOn(obj, 'method')Spy on an existing method without replacing it
vi.spyOn(obj, 'method').mockReturnValue(val)Spy and override return value
jest.mock('./module') / vi.mock('./module')Auto-mock all exports of a module
jest.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 module
jest.resetAllMocks() / vi.resetAllMocks()Reset all mock implementations and call history
jest.clearAllMocks() / vi.clearAllMocks()Clear call history on all mocks

Mock Assertions

expect(mockFn).toHaveBeenCalled()Mock was called at least once
expect(mockFn).not.toHaveBeenCalled()Mock was never called
expect(mockFn).toHaveBeenCalledTimes(n)Mock was called exactly n times
expect(mockFn).toHaveBeenCalledWith(arg1, arg2)Mock was called with specific arguments at least once
expect(mockFn).toHaveBeenLastCalledWith(arg)Last call to mock had these arguments
expect(mockFn).toHaveBeenNthCalledWith(n, arg)nth call to mock had these arguments (1-indexed)
expect(mockFn).toHaveReturnedWith(val)Mock returned given value at least once
mockFn.mock.callsArray of argument arrays for each call
mockFn.mock.calls[0]Arguments of the first call
mockFn.mock.resultsArray of {type, value} for each call return
mockFn.mock.instancesArray of this-context for each call (new usage)
mockFn.mock.calls.lengthTotal number of times the mock was called
mockFn.mock.results[0].valueReturn value of the first call

Snapshot Testing

expect(val).toMatchSnapshot()Save snapshot on first run; assert equality on subsequent runs
expect(val).toMatchInlineSnapshot()Inline snapshot stored directly in test file
expect(val).toMatchSnapshot('name')Named snapshot - useful when multiple snapshots per test
npx jest --updateSnapshot / npx vitest --update-snapshots / -uUpdate failing snapshots
expect(val).toMatchFileSnapshot('./path.txt')Snapshot stored in a specific file (Vitest only)
jest.addSnapshotSerializer(serializer)Register a custom snapshot serializer
Snapshots stored in __snapshots__/Auto-created directory next to test files
Delete .snap file to regenerateRemove the snapshot file to recreate from scratch

Module 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 export
vi.mock('./mod', () => ({ namedFn: vi.fn() }))Mock named export
vi.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 matter

Coverage

npx jest --coverageGenerate code coverage report with Jest
npx vitest --coverageGenerate code coverage report with Vitest
collectCoverage: trueAlways collect coverage in jest.config.js
coverageThreshold: { 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 coverage
coverageReporters: ['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