vitest-testing

Vitest Testing Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "vitest-testing" with this command: npx skills add janisto/fastify-playground/janisto-fastify-playground-vitest-testing

Vitest Testing Patterns

This skill provides patterns for writing unit tests with Vitest in this repository.

Test Structure

  • Unit tests: app/tests/unit/** (mirror app/src/** structure)

  • Integration tests: app/tests/integration/**

  • Mocks: app/tests/mocks/**

  • Helpers: app/tests/helpers/**

Plugin Test Template

import Fastify from "fastify"; import { afterEach, describe, expect, it } from "vitest"; import pluginName from "../../../src/plugins/plugin-name.js";

describe("Plugin Name", () => { let fastify: ReturnType<typeof Fastify>;

afterEach(async () => { if (fastify) await fastify.close(); });

it("should register plugin successfully", async () => { fastify = Fastify(); await fastify.register(pluginName); await fastify.ready();

// Test expectations
expect(fastify.hasDecorator("decoratorName")).toBe(true);

}); });

Route Test Template

import Fastify from "fastify"; import { afterEach, describe, expect, it } from "vitest"; import routeName from "../../../src/routes/route-name.js";

describe("GET /endpoint", () => { let fastify: ReturnType<typeof Fastify>;

afterEach(async () => { if (fastify) await fastify.close(); });

it("should return expected response", async () => { fastify = Fastify(); await fastify.register(routeName);

const response = await fastify.inject({
  method: "GET",
  url: "/endpoint",
});

expect(response.statusCode).toBe(200);
expect(response.json()).toEqual({ status: "healthy" });

});

it("should return 400 for invalid input", async () => { fastify = Fastify(); await fastify.register(routeName);

const response = await fastify.inject({
  method: "POST",
  url: "/endpoint",
  payload: { invalid: "data" },
});

expect(response.statusCode).toBe(400);

}); });

Key Patterns

Fastify Instance

  • Use Fastify() to create test instances

  • Always call await fastify.ready() after registering plugins

  • Always call await fastify.close() after tests (use afterEach hook)

Request Simulation

Use fastify.inject() for HTTP request simulation:

const response = await fastify.inject({ method: "GET", url: "/endpoint", headers: { authorization: "Bearer token" }, query: { param: "value" }, payload: { data: "value" }, });

Response Assertions

expect(response.statusCode).toBe(200); expect(response.headers["content-type"]).toContain("application/json"); expect(response.json()).toEqual({ expected: "data" });

Testing Decorators

it("should decorate fastify instance", async () => { const fastify = Fastify(); await fastify.register(plugin); await fastify.ready();

expect(fastify.hasDecorator("myDecorator")).toBe(true); expect(fastify.myDecorator).toBeDefined();

await fastify.close(); });

Coverage Requirements

  • Provider: V8

  • Minimum thresholds: 70% (lines, functions, branches, statements)

  • Target: 90%+ overall, 100% for critical business logic

  • Scope: Only tests/unit/** affects coverage metrics

V8 Coverage Ignore

Use /* v8 ignore next -- @preserve */ to exclude untestable code:

// ignore single statement /* v8 ignore next -- @preserve */ process.on("SIGTERM", () => gracefulShutdown());

// ignore block /* v8 ignore start -- @preserve / const handler = setupHandler(); process.on("SIGINT", handler); / v8 ignore stop -- @preserve */

The -- @preserve suffix prevents esbuild from stripping comments.

Import Conventions

  • Use .js extensions for relative imports

  • Use import type { ... } from "pkg" for type-only imports

  • Vitest globals are enabled but explicit imports are preferred for better IntelliSense, type checking, and refactoring support: import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

Commands

cd app npm run test # Run all tests npm run test:watch # Run tests in watch mode npm run test:coverage # Run tests with coverage report

Boundaries

  • No real network, filesystem, or database calls in unit tests

  • Each source file should have a matching test file

  • Do not skip tests without documenting the reason

  • Do not add inline Vitest env comments

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

fastify-routes

No summary provided by upstream source.

Repository SourceNeeds Review
General

fastify-plugin

No summary provided by upstream source.

Repository SourceNeeds Review
General

typebox-schemas

No summary provided by upstream source.

Repository SourceNeeds Review
General

vitest-testing

No summary provided by upstream source.

Repository SourceNeeds Review