All free skills / Other majors
vitest 4.x
Run isolated tests with module mocks, timer lifecycle and explicit async assertions.
- For
vitest@4.1.11- Verified
- 2026-10-10, 8 examples executed
- Skill package
@modootoday/pmcp-vitest@4.0.0
Use this skill for free
No PMCP login or subscription is required. Download the original instructions, or install the content-only archive with your project's package manager.
Download SKILL.md · Download package archive
npm install --save-dev https://pmcp.build/skills/vitest/4/package.tgz
PMCP discovers the installed package's instructions. Connect your runtime after installation.
Archive integrity
sha512-2g6c6oPfKMEPosKy08RrBO5Phsmrp/C21jspf0eNsKK28QGzDXGRNN2Qmos8vZmEsX0D2CchfqZEDqo55RSqXQ==Complete instructions
Vitest 4 development workflow
This skill targets Vitest 4.1.11. Read the installed Vitest version, scripts, configuration, and environment before applying examples. Use the versioned Vitest 4 documentation for this major line; do not copy Vitest 5-only APIs into a 4.x suite.
Run real tests
Place test/it callbacks in files discovered by Vitest and execute the project test script or its local vitest run command. Import expect, test, hooks, and vi from vitest unless the project intentionally enables globals.
A direct node or bun execution is not a substitute for Vitest's runner and module transformation. Do not mark imported vi helpers or unexecuted test callbacks as a passing suite.
import { expect, test } from "vitest";
test("rejects an unavailable record", async () => {
const readRecord = async () => {
throw new Error("unavailable");
};
await expect(readRecord()).rejects.toThrow("unavailable");
});
Await promise assertions and asynchronous work. A test that finishes before an assertion runs can report misleading success. Select node, jsdom, happy-dom, or Browser Mode to match the system under test; changing environments can change what a passing test proves.
Preserve the project's execution policy
Use a focused file or name filter while developing. On a constrained machine, an explicit one-worker, non-parallel-file run can bound resource use:
vitest run path/to/feature.test.ts --maxWorkers=1 --no-file-parallelism
This is an invocation choice, not a reason to overwrite a project's established pool, browser provider, isolation, coverage, or projects configuration. Vitest 4 removed poolOptions and moved its supported settings to their new locations; check the migration guide when upgrading. See fileParallelism and maxWorkers for the CLI options.
Mock the dependency boundary
vi.mock is hoisted by the runner. Use vi.hoisted for state required by the mock factory, or keep the factory self-contained. Prefer the import-promise form for typed module paths. Call the system under test and assert its observable result as well as the relevant dependency interaction.
import { expect, test, vi } from "vitest";
import { readUser } from "./service.js";
import { findUser } from "./repository.js";
vi.mock(import("./repository.js"), () => ({
findUser: vi.fn(async (id: string) => ({ id, name: "Ada" })),
}));
test("reads a user through its repository", async () => {
await expect(readUser("u1")).resolves.toBe("Ada");
expect(findUser).toHaveBeenCalledWith("u1");
});
Mocking an exported function does not replace calls to that function from inside the same module. Choose a separable dependency boundary when that matters. ESM namespace spying also differs in Browser Mode; a Node suite does not establish that a browser mock works. See the mocking guide.
Keep cleanup intentional
| Operation | Intended effect |
|---|---|
| mockClear / clearAllMocks | Clear recorded calls while preserving the implementation. |
| mockReset / resetAllMocks | Clear mock state and reset implementations; vi.fn(initialImplementation) resets to its initial implementation. |
| mockRestore / restoreAllMocks | Restore spied-on original methods. In Vitest 4, restoreAllMocks does not clear each spy's recorded history or restore automocked exports. |
Choose clearMocks, mockReset, and restoreMocks for the suite's intended state model rather than enabling all of them blindly. Restore fake timers and explicit global/environment stubs even when assertions fail:
import { afterEach, expect, test, vi } from "vitest";
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
vi.unstubAllGlobals();
vi.unstubAllEnvs();
});
test("resolves after a delay", async () => {
vi.useFakeTimers();
const result = new Promise((resolve) => {
setTimeout(() => resolve("ready"), 100);
});
await vi.advanceTimersByTimeAsync(100);
await expect(result).resolves.toBe("ready");
});
Do not combine fake timers and concurrent tests sharing global state. The vi API documents reset and restoration behavior.
Completion evidence
Check the runner exit code and executed test count. Distinguish passing tests, expected failures, skipped tests, and failures; an empty run or generated report alone is not proof of success. Report the exact Vitest version, environment, and targeted command. Coverage and typechecking are separate checks: transformed TypeScript tests do not prove their types are valid.