All skills
antfu avatar

/vitest

@d02c484 official
by Anthony Fuantfu/skills5.9k stars
335

Vitest fast unit testing framework powered by Vite with Jest-compatible API. Use when writing tests, mocking, configuring coverage, or working with test filtering and fixtures.

Use this Skill: https://skilld.dev/gh/antfu/skills/vitest

This session only. Nothing lands on disk.

referencesadvanced-vi.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Vi Utilities

The vi helper provides mocking and utility functions.

import { vi } from 'vitest'

Mock Functions

// Create mock
const fn = vi.fn()
const fnWithImpl = vi.fn((x) => x * 2)

// Check if mock
vi.isMockFunction(fn) // true

// Mock methods
fn.mockReturnValue(42)
fn.mockReturnValueOnce(1)
fn.mockResolvedValue(data)
fn.mockRejectedValue(error)
fn.mockImplementation(() => 'result')
fn.mockImplementationOnce(() => 'once')

// Clear/reset
fn.mockClear()    // Clear call history
fn.mockReset()    // Clear history + implementation
fn.mockRestore()  // Restore original (for spies)

Spying

const obj = { method: () => 'original' }

const spy = vi.spyOn(obj, 'method')
obj.method()

expect(spy).toHaveBeenCalled()

// Mock implementation
spy.mockReturnValue('mocked')

// Spy on getter/setter
vi.spyOn(obj, 'prop', 'get').mockReturnValue('value')

Module Mocking

// Hoisted to top of file
vi.mock('./module', () => ({
  fn: vi.fn(),
}))

// Partial mock
vi.mock('./module', async (importOriginal) => ({
  ...(await importOriginal()),
  specificFn: vi.fn(),
}))

// Spy mode - keep implementation
vi.mock('./module', { spy: true })

// Import actual module inside mock
const actual = await vi.importActual('./module')

// Import as mock
const mocked = await vi.importMock('./module')

Dynamic Mocking

// Not hoisted - use with dynamic imports
vi.doMock('./config', () => ({ key: 'value' }))
const config = await import('./config')

// Unmock
vi.doUnmock('./config')
vi.unmock('./module') // Hoisted

Conditional Mocking — vi.when (v5)

Argument-specific spy behaviors:

vi.when(spy)
  .calledWith(1).thenReturn('one')
  .calledWith(2).thenReturn('two')

// then* actions: thenReturn / thenThrow / thenResolve / thenReject (+ *Once)
// options: { times }, second arg { onUnmatched: 'throw' | 'passthrough' | fn }

vi.isWhenChain(w)  // type guard for a When chain

See features-mocking for FIFO/LIFO matching and toHaveBeenExhausted.

Assertion Helpers — vi.defineHelper (4.1+)

Wrap reusable assertion functions so failures point at the call site, not inside the helper:

const expectValidUser = vi.defineHelper((user: unknown) => {
  expect(user).toHaveProperty('id')
  expect(user).toHaveProperty('email')
})

test('returns a valid user', async () => {
  expectValidUser(await fetchUser('alice')) // failures reported here
})

Reset Modules

// Clear module cache
vi.resetModules()

// Wait for dynamic imports
await vi.dynamicImportSettled()

Fake Timers

vi.useFakeTimers()

// Choose which timers to fake (toFake and toNotFake are mutually exclusive)
vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout'] })
vi.useFakeTimers({ toNotFake: ['setInterval'] })

// v5: Temporal is faked alongside Date when present on globalThis;
// exclude it with toNotFake: ['Temporal']

setTimeout(() => console.log('done'), 1000)

// Advance time
vi.advanceTimersByTime(1000)
vi.advanceTimersByTimeAsync(1000)  // For async callbacks
vi.advanceTimersToNextTimer()
vi.advanceTimersToNextFrame()      // requestAnimationFrame

// Run all timers
vi.runAllTimers()
vi.runAllTimersAsync()
vi.runOnlyPendingTimers()

// Clear timers
vi.clearAllTimers()

// Check state
vi.getTimerCount()
vi.isFakeTimers()

// Restore
vi.useRealTimers()

Mock Date/Time

vi.setSystemTime(new Date('2024-01-01'))
expect(new Date().getFullYear()).toBe(2024)
// v5: also drives Temporal.Now when Temporal is available

vi.getMockedSystemTime()  // Get mocked date
vi.getRealSystemTime()    // Get real time (ms)

Global/Env Mocking

// Stub global
vi.stubGlobal('fetch', vi.fn())
vi.unstubAllGlobals()

// Stub environment
vi.stubEnv('API_KEY', 'test')
vi.stubEnv('NODE_ENV', 'test')
vi.unstubAllEnvs()

Hoisted Code

Run code before imports:

const mock = vi.hoisted(() => vi.fn())

vi.mock('./module', () => ({
  fn: mock, // Can reference hoisted variable
}))

Waiting Utilities

// Wait for callback to succeed
await vi.waitFor(async () => {
  const el = document.querySelector('.loaded')
  expect(el).toBeTruthy()
}, { timeout: 5000, interval: 100 })

// Wait for truthy value
const element = await vi.waitUntil(
  () => document.querySelector('.loaded'),
  { timeout: 5000 }
)

Mock Object

Mock all methods of an object:

const original = {
  method: () => 'real',
  nested: { fn: () => 'nested' },
}

const mocked = vi.mockObject(original)
mocked.method()  // undefined (mocked)
mocked.method.mockReturnValue('mocked')

// Spy mode
const spied = vi.mockObject(original, { spy: true })
spied.method()  // 'real'
expect(spied.method).toHaveBeenCalled()

Test Configuration

vi.setConfig({
  testTimeout: 10_000,
  hookTimeout: 10_000,
})

vi.resetConfig()

Global Mock Management

vi.clearAllMocks()   // Clear all mock call history
vi.resetAllMocks()   // Reset + clear implementation
vi.restoreAllMocks() // Restore originals (spies)

vi.mocked Type Helper

TypeScript helper for mocked values:

import { myFn } from './module'
vi.mock('./module')

// Type as mock
vi.mocked(myFn).mockReturnValue('typed')

// Deep mocking
vi.mocked(myModule, { deep: true })

// Partial mock typing
vi.mocked(fn, { partial: true }).mockResolvedValue({ ok: true })

Key Points

  • vi.mock is hoisted - use vi.doMock for dynamic mocking
  • vi.hoisted lets you reference variables in mock factories
  • Use vi.spyOn to spy on existing methods (v4: supports constructors)
  • Use vi.when for argument-specific behaviors and vi.defineHelper for assertion helpers
  • Fake timers require explicit setup and teardown
  • vi.waitFor retries until assertion passes
<!-- Source references: - https://vitest.dev/api/vi.html -->

Source: SKILL.md on GitHub

No alerts3d5 checks · Risk SAFE
  • Gen Agent Trust Hub3d

    The skill provides comprehensive documentation and reference material for the Vitest testing framework. It covers configuration, CLI usage, mocking, coverage, and advanced features like type testing and benchmarking. No security issues were detected; the instructions follow standard development and testing practices.

  • Socket3d

    No alerts

  • Snyk3d

    Risk: LOW · No issues

  • Runlayer7mo

    1/18 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at d02c484. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated 4 days ago
Other metadata
metadata
{
  "author": "Anthony Fu",
  "version": "2026.9.25",
  "source": "Generated from https://github.com/vitest-dev/vitest, scripts located at https://github.com/antfu/skills"
}

README badge

README badge for antfu/skills/vitest

Vitest is a Jest-compatible unit testing framework powered by Vite, with native ESM, TypeScript, and JSX support. Use it for writing tests with smart watch mode, mocking, fixtures, coverage reporting, and snapshot testing in projects already using Vite.

Generated from the current SKILL.md.

Is Vitest a drop-in replacement for Jest?
Mostly. Vitest provides a Jest-compatible API and can run most Jest test suites without modification, but it uses Vite's transformation pipeline instead of Jest's, so some edge cases may differ.
Does Vitest require configuration?
No. It natively supports ESM, TypeScript, and JSX out of the box and shares Vite's config, transformers, and resolvers, so many projects need minimal or no additional setup.
What coverage providers does Vitest support?
Vitest includes built-in coverage via V8 or Istanbul providers.
Can I run tests in parallel?
Yes. Vitest uses multi-threaded workers for parallel test execution and supports sharding across multiple processes.
What test environments are available?
Vitest supports node, jsdom, happy-dom, and custom environments.

Generated from the current SKILL.md. These answers refresh after source changes.