Files
stack/packages/mosaic/framework/skills/vitest/references/advanced-vi.md
T
fargo 1a822493ba format: apply repo prettier (3.8.1) to the folded skills tree
963 markdown files reformatted with the repository's pinned prettier so
pnpm format:check covers the folded tree like every other repo file.

The formatter's embedded-language pass also normalized code fences
(TS semicolons, closed HTML tags in examples, lowercased CSS hex colors,
one renumbered list that skipped an index). Alphanumeric token deltas vs
the fold commit were audited file-by-file; all are formatter-equivalent
markup normalizations plus the four sanitized skills.
2026-08-19 14:37:17 -05:00

4.5 KiB

name, description
name description
vi-utilities vi helper for mocking, timers, utilities

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

Reset Modules

// Clear module cache
vi.resetModules();

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

Fake Timers

vi.useFakeTimers();

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);

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
  • Fake timers require explicit setup and teardown
  • vi.waitFor retries until assertion passes