Vitest Cheatsheet
Matchers Reference
Use this Vitest reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Equality
| Matcher | Passes When |
|---|---|
.toBe(val) | Object.is(received, val) — strict, reference-equal for objects |
.toEqual(val) | Deep recursive equality (ignores undefined object props) |
.toStrictEqual(val) | Deep equality + checks undefined props + class type |
.not.toBe(val) | Negation of .toBe |
expect(1).toBe(1) expect({ a: 1 }).toEqual({ a: 1 }) expect(new Date('2024-01-01')).toStrictEqual(new Date('2024-01-01'))
Truthiness
| Matcher | Passes When |
|---|---|
.toBeTruthy() | !!received is true |
.toBeFalsy() | !!received is false |
.toBeNull() | received === null |
.toBeUndefined() | received === undefined |
.toBeDefined() | received !== undefined |
.toBeNaN() | Number.isNaN(received) |
Numbers
| Matcher | Passes When |
|---|---|
.toBeGreaterThan(n) | received > n |
.toBeGreaterThanOrEqual(n) | received >= n |
.toBeLessThan(n) | received < n |
.toBeLessThanOrEqual(n) | received <= n |
.toBeCloseTo(n, d?) | Within 10^-d / 2 of n (default d=2) |
Strings
| Matcher | Passes When |
|---|---|
.toContain(str) | received.includes(str) |
.toMatch(str|regex) | Regex test or includes |
.toHaveLength(n) | received.length === n |
expect('hello world').toMatch(/\w+/) expect('foobar').toContain('oob') expect('foobar').toMatch(/^foo/)
Arrays & Iterables
| Matcher | Passes When |
|---|---|
.toContain(item) | Array contains item (strict ===) |
.toContainEqual(item) | Array contains item (deep equality) |
.toHaveLength(n) | .length === n |
.toEqual(expect.arrayContaining([...])) | Array is a superset of expected items |
expect([1, 2, 3]).toContain(2) expect([{ id: 1 }]).toContainEqual({ id: 1 }) expect([1, 2, 3, 4]).toEqual(expect.arrayContaining([2, 4]))
Objects
| Matcher | Passes When |
|---|---|
.toMatchObject(subset) | Object contains at least subset (deep partial match) |
.toHaveProperty(path, val?) | Property at dot/bracket path exists (and equals val) |
.toEqual(expect.objectContaining({...})) | Object is a superset of expected |
expect({ a: 1, b: 2 }).toMatchObject({ a: 1 }) expect({ user: { id: 42 } }).toHaveProperty('user.id', 42) expect({ a: 1, b: 2 }).toMatchObject(expect.objectContaining({ a: 1 }))
Errors
| Matcher | Passes When |
|---|---|
.toThrow() | Function throws anything |
.toThrow(str) | Error message contains str |
.toThrow(regex) | Error message matches regex |
.toThrow(ErrorClass) | thrown instanceof ErrorClass |
.toThrowError(...) | Alias of .toThrow |
.toThrowErrorMatchingSnapshot() | Error message matches stored snapshot |
.toThrowErrorMatchingInlineSnapshot(str) | Error message matches inline snapshot |
expect(() => JSON.parse('bad')).toThrow(SyntaxError) expect(() => fn()).toThrow('invalid input')
Promises
| Matcher | Usage |
|---|---|
.resolves.toBe(val) | await expect(p).resolves.toBe(val) |
.resolves.toEqual(val) | Deep equality on resolved value |
.rejects.toThrow(...) | await expect(p).rejects.toThrow(...) |
.rejects.toBeInstanceOf(Cls) | Rejected value is instance of class |
Spies & Mocks
| Matcher | Passes When |
|---|---|
.toHaveBeenCalled() | Called at least once |
.toHaveBeenCalledTimes(n) | Called exactly n times |
.toHaveBeenCalledWith(...args) | Any call matches args |
.toHaveBeenLastCalledWith(...args) | Last call matches args |
.toHaveBeenNthCalledWith(n, ...args) | nth call matches args |
.toHaveReturned() | Called and did not throw |
.toHaveReturnedTimes(n) | Returned (not thrown) n times |
.toHaveReturnedWith(val) | Any return value matches |
.toHaveLastReturnedWith(val) | Last return value matches |
.toHaveNthReturnedWith(n, val) | nth return value matches |
const fn = vi.fn().mockReturnValue(42) fn('x'); fn('y') expect(fn).toHaveBeenCalledTimes(2) expect(fn).toHaveBeenNthCalledWith(1, 'x') expect(fn).toHaveLastReturnedWith(42)
Snapshots
| Matcher | Effect |
|---|---|
.toMatchSnapshot() | Compare to stored .snap file |
.toMatchInlineSnapshot(str) | Compare to inline string |
.toMatchFileSnapshot(path) | Compare to external file |
.toThrowErrorMatchingSnapshot() | Error message vs stored snapshot |
Type Matchers (expect.any / expect.anything)
| Asymmetric Matcher | Matches |
|---|---|
expect.any(Constructor) | Any instance of Constructor |
expect.anything() | Anything except null / undefined |
expect.arrayContaining([...]) | Array is superset of given items |
expect.objectContaining({...}) | Object is superset of given shape |
expect.stringContaining(str) | String includes str |
expect.stringMatching(regex|str) | String matches regex or contains str |
expect.not.arrayContaining([...]) | Does NOT contain all given items |
expect.not.objectContaining({...}) | Does NOT contain given shape |
expect.not.stringContaining(str) | Does NOT contain str |
expect.not.stringMatching(regex) | Does NOT match regex |
expect({ id: 1, createdAt: new Date() }).toMatchObject({ id: expect.any(Number), createdAt: expect.any(Date), }) expect(fn).toHaveBeenCalledWith( expect.objectContaining({ role: 'admin' }), expect.anything() )
Assertion Control
| Method | Effect |
|---|---|
expect.assertions(n) | Exactly n assertions must run in the test |
expect.hasAssertions() | At least 1 assertion must run |
expect.soft(val) | Record failure but don't stop the test |
expect.extend({...}) | Add custom matchers |
expect.addSnapshotSerializer(...) | Add custom snapshot formatter |
Extra Matchers (jest-extended)
Not built into Vitest — these come from the jest-extended package (Vitest-compatible):
npm install -D jest-extended
// setup.ts import * as matchers from 'jest-extended' import { expect } from 'vitest' expect.extend(matchers)
| Matcher | Passes When |
|---|---|
.toStartWith(prefix) | received.startsWith(prefix) |
.toEndWith(suffix) | received.endsWith(suffix) |
.toBePositive() | received > 0 |
.toBeNegative() | received < 0 |
.toBeEven() | received % 2 === 0 |
.toBeOdd() | received % 2 !== 0 |
.toBeFinite() | Number.isFinite(received) |
.toBeInteger() | Number.isInteger(received) |
.toBeEmpty() | String/array/object is empty |
.toIncludeAllMembers([...]) | Array contains all given members |
DOM Matchers (@testing-library/jest-dom)
Install: npm install -D @testing-library/jest-dom
// setup.ts import '@testing-library/jest-dom'
| Matcher | Passes When |
|---|---|
.toBeInTheDocument() | Element is in the DOM |
.toBeVisible() | Element is visible |
.toBeDisabled() | Element is disabled |
.toBeEnabled() | Element is not disabled |
.toBeChecked() | Checkbox/radio is checked |
.toHaveValue(val) | Input has value |
.toHaveTextContent(str) | Element text contains str |
.toHaveAttribute(attr, val?) | Element has attribute (optional value) |
.toHaveClass(...classes) | Element has CSS classes |
.toHaveFocus() | Element has focus |
.toHaveStyle(css) | Element has CSS style |
.toHaveDisplayValue(val) | Select/textarea display value |
.toBeEmptyDOMElement() | Element has no children |
.toContainElement(el) | Element contains child element |
.toContainHTML(html) | DOM contains html string |
import { render, screen } from '@testing-library/react' render(<button disabled>Submit</button>) expect(screen.getByRole('button')).toBeDisabled() expect(screen.getByRole('button')).toHaveTextContent('Submit')