Vitest
Configuration
Section titled “Configuration”Root vitest.config.ts:
import { defineConfig } from "@repo/vitest-config"
export default defineConfig()The shared config from @repo/vitest-config provides sensible defaults.
Writing Tests
Section titled “Writing Tests”import { beforeEach, describe, expect, it, vi } from "vitest"
describe("MyFeature", () => { beforeEach(() => { // Setup before each test })
it("should do something", () => { const result = myFunction() expect(result).toBe(expected) })
it("should handle errors", () => { expect(() => errorFunction()).toThrow("Error message") })})Assertions
Section titled “Assertions”// Equalityexpect(value).toBe(expected) // Strict equalityexpect(value).toEqual(expected) // Deep equalityexpect(value).toStrictEqual(expected) // Strict deep equality
// Truthinessexpect(value).toBeTruthy()expect(value).toBeFalsy()expect(value).toBeNull()expect(value).toBeUndefined()
// Numbersexpect(value).toBeGreaterThan(3)expect(value).toBeLessThan(10)expect(value).toBeCloseTo(0.3, 5)
// Stringsexpect(string).toContain("substring")expect(string).toMatch(/pattern/)
// Arrays/Objectsexpect(array).toContain(item)expect(array).toHaveLength(3)expect(object).toHaveProperty("key", "value")
// Errorsexpect(() => fn()).toThrow()expect(() => fn()).toThrow("message")expect(() => fn()).toThrow(ErrorClass)
// Asyncawait expect(promise).resolves.toBe(value)await expect(promise).rejects.toThrow()Mocking
Section titled “Mocking”Mock Functions
Section titled “Mock Functions”const mockFn = vi.fn()mockFn.mockReturnValue(42)mockFn.mockResolvedValue(data) // AsyncmockFn.mockImplementation((x) => x * 2)
// Verify callsexpect(mockFn).toHaveBeenCalled()expect(mockFn).toHaveBeenCalledWith(arg1, arg2)expect(mockFn).toHaveBeenCalledTimes(3)Mock Modules
Section titled “Mock Modules”vi.mock("./module", () => ({ myFunction: vi.fn(() => "mocked"),}))
// Or with factoryvi.mock("./module", async (importOriginal) => { const original = await importOriginal() return { ...original, myFunction: vi.fn(), }})const spy = vi.spyOn(object, "method")spy.mockReturnValue("mocked")
// After testspy.mockRestore()Test Organization
Section titled “Test Organization”File Naming
Section titled “File Naming”src/├── things.ts└── things.test.ts # Co-located testOr in dedicated folder:
src/├── things.ts└── __tests__/ └── things.test.tsTest Validators
Section titled “Test Validators”import { describe, expect, it } from "vitest"
import { createThingSchema } from "./things"
describe("createThingSchema", () => { it("validates correct input", () => { const result = createThingSchema.safeParse({ title: "Test", }) expect(result.success).toBe(true) })
it("rejects empty title", () => { const result = createThingSchema.safeParse({ title: "", }) expect(result.success).toBe(false) })})Commands
Section titled “Commands”# Run all testsbun test
# Watch modebun test:watch
# Run specific filebun test src/things.test.ts
# With coveragebun test --coverage
# Run in specific packageturbo test --filter=@repo/validatorsConfiguration Options
Section titled “Configuration Options”In vitest.config.ts:
import { defineConfig } from "vitest/config"
export default defineConfig({ test: { globals: true, // Use global expect, describe, it environment: "node", // or "jsdom" for browser coverage: { provider: "v8", reporter: ["text", "html"], }, include: ["**/*.test.ts"], exclude: ["**/node_modules/**"], },})