Skip to content
Back to skills

Vitest

ASecurity

Vitest gotchas for mocking, timers, type tests and coverage. Use when writing or debugging Vitest tests, configuring vitest.config, or a coverage threshold fails.

  • 80 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 28, 2026
ai-agentsgonodetestingdebuggingapidatabase

Works with

  • terminal
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add monkilabs/opencastle --skill vitest-testing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Vitest?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Vitest
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/monkilabs-vitest/badge)](https://www.skillsdirectory.com/skills/monkilabs-vitest)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: vitest-testing
description: "Vitest gotchas for mocking, timers, type tests and coverage. Use when writing or debugging Vitest tests, configuring vitest.config, or a coverage threshold fails."
---

# Vitest Testing

Project test configuration: `.opencastle/stack/testing-config.md`. Coverage thresholds, environment and setup files: the project's `vitest.config.*` (or the `test` block of `vite.config.*`) — read them, never assume a number.

## Running

- `vitest` alone starts **watch mode** in a terminal and never exits. Agents run `vitest run [file] [-t "name"]`.
- Type tests (`*.test-d.ts`, `expectTypeOf`) run with `vitest --typecheck` (or `vitest run --typecheck`). The old `vitest typecheck` subcommand is gone since 1.0.
- Coverage: `vitest run --coverage`. Below threshold → read the uncovered lines in the text report, add tests for those branches, re-run.

## Mocking gotchas

- **`vi.mock()` is hoisted** above every import, so its factory cannot use variables declared in the file. Declare them with `vi.hoisted()`:

  ```ts
  const { getUser } = vi.hoisted(() => ({ getUser: vi.fn() }))
  vi.mock('./database', () => ({ getUser }))
  ```

- Partial mock: `vi.mock('./config', async (importOriginal) => ({ ...(await importOriginal<typeof import('./config')>()), API_URL: 'http://test' }))`.
- `vi.spyOn(namespace, 'fn')` on a module's export misses calls made inside that module, and fails in Browser Mode; mock the module instead.
- **`vi.restoreAllMocks()` only restores `vi.spyOn` spies** (Vitest 3+). It does not reset `vi.fn()` call history; use `vi.clearAllMocks()`, or `restoreMocks` / `clearMocks` in the config, so state cannot leak between tests.
- Fake timers: `vi.useFakeTimers()` in `beforeEach`, `vi.useRealTimers()` in `afterEach`; advance with `vi.advanceTimersByTime(ms)` or `await vi.advanceTimersByTimeAsync(ms)` when promises are involved.
- One file needs a DOM in a `node` project: `// @vitest-environment jsdom` on its first line.

Files in this skill

  • SKILL.md4.7 KB
  • config.ts427 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.