Skip to main content

typescript-testing

TypeScript/JavaScript testing practices with Bun's test runner. Activate when working with bun test, .test.ts, .test.js, .spec.ts, .spec.js, testing TypeScript/JavaScript, bunfig.toml, testing configuration, or test-related tasks in Bun projects.

来源信息

仓库
ilude/claude-code-config
最近来源活动
2025年11月17日 23:00
检测到的 SKILL.md 语言
英语
星标
8
Forks
0

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
typescript-testing
description
TypeScript/JavaScript testing practices with Bun's test runner. Activate when working with bun test, .test.ts, .test.js, .spec.ts, .spec.js, testing TypeScript/JavaScript, bunfig.toml, testing configuration, or test-related tasks in Bun projects.
# TypeScript Testing with Bun TypeScript/JavaScript-specific testing patterns and best practices using Bun's built-in test runner, complementing general testing-workflow skill. ## CRITICAL: Bun Test Execution **NEVER use jest, vitest, or other test runners in Bun projects:** ```bash # ✅ CORRECT - Bun test execution bun test bun test --watch bun test src/__tests__ bun test --coverage bun test --bail bun test tests/unit.test.ts # ❌ WRONG - Never use jest in Bun projects # ❌ jest # ❌ jest --watch # ❌ npm run test (if mapped to jest) # ❌ WRONG - Never use vitest in Bun projects # ❌ vitest # ❌ vitest run ``` **Always use `bun test` directly** (never use jest/vitest in Bun projects). --- ## Test File Organization ### File Naming Conventions Bun recognizes test files by standard conventions: ``` src/ ├── utils/ │ ├── math.ts │ ├── math.test.ts # ✅ Standard .test.ts │ ├── string-utils.spec.ts # ✅ Alternative .spec.ts │ └── validation/ │ ├── validator.ts │ └── validator.test.ts ├── services/ │ ├── api.ts │ └── __tests__/ # ✅ __tests__ directory │ └── api.test.ts └── components/ ├── Button.tsx └── Button.test.tsx # ✅ React component tests ``` ### Discovery Patterns Bun automatically finds tests matching: - `*.test.ts` / `*.test.tsx` - `*.test.js` / `*.test.jsx` - `*.spec.ts` / `*.spec.tsx` - `*.spec.js` / `*.spec.jsx` - Files in `__tests__` directories --- ## Basic Test Structure ### Simple Test Example ```typescript import { describe, it, expect } from "bun:test"; import { add, multiply } from "./math"; describe("Math utilities", () => { it("should add two numbers", () => { expect(add(2, 3)).toBe(5); }); it("should multiply two numbers", () => { expect(multiply(4, 5)).toBe(20); }); it("should handle negative numbers", () => { expect(add(-1, -2)).toBe(-3); }); }); ``` ### Describe Blocks Organize tests with nested describe blocks: ```typescript import { describe, it, expect } from "bun:test"; import { UserService } from "./user-service"; describe("UserService", () => { describe("create", () => { it("should create user with valid data", () => { // Test implementation }); it("should throw error on invalid email", () => { // Test implementation }); }); describe("update", () => { it("should update user properties", () => { // Test implementation }); it("should not update protected fields", () => { // Test implementation }); }); describe("delete", () => { it("should delete user by id", () => { // Test implementation }); }); }); ``` --- ## Bun Test API ### Describe and It ```typescript import { describe, it, expect } from "bun:test"; describe("Feature name", () => { it("should do something", () => { expect(true).toBe(true); }); it("should handle edge case", () => { expect(() => riskyOperation()).toThrow(); }); }); ``` ### Common Assertions ```typescript import { expect } from "bun:test"; // Equality expect(value).toBe(5); // Strict equality (===) expect(obj).toEqual({ a: 1 }); // Deep equality expect(value).toStrictEqual(5); // Strict deep equality // Truthiness expect(value).toBeTruthy(); // Truthy value expect(value).toBeFalsy(); // Falsy value expect(value).toBeNull(); // null expect(value).toBeUndefined(); // undefined expect(value).toBeDefined(); // Not undefined // Numbers expect(number).toBeGreaterThan(5); expect(number).toBeGreaterThanOrEqual(5); expect(number).toBeLessThan(10); expect(number).toBeLessThanOrEqual(10); expect(0.1 + 0.2).toBeCloseTo(0.3); // Float comparison // Strings expect(string).toMatch(/pattern/); expect(string).toContain("substring"); // Arrays expect(array).toContain(value); expect(array).toHaveLength(3); // Objects expect(obj).toHaveProperty("key"); expect(obj).toHaveProperty("key", expectedValue); // Exceptions expect(() => throwError()).toThrow(); expect(() => throwError()).toThrow(CustomError); expect(() => throwError()).toThrow(/error message/); ``` ### Skipping and Only ```typescript import { it, describe } from "bun:test"; describe("Feature", () => { it("should test this", () => { // Runs }); it.skip("should skip this test", () => { // Skipped }); it.only("should run only this test", () => { // Only this runs in the suite }); describe.skip("skipped suite", () => { it("won't run", () => {}); }); }); ``` ### Test.todo ```typescript import { it } from "bun:test"; it.todo("feature not yet implemented"); it.todo("edge case to handle"); ``` --- ## Setup and Teardown ### beforeEach and afterEach ```typescript import { describe, it, beforeEach, afterEach, expect } from "bun:test"; import { Database } from "./database"; describe("Database operations", () => { let db: Database; beforeEach(() => { // Setup before each test db = new Database(":memory:"); db.initialize(); }); afterEach(() => { // Cleanup after each test db.close(); }); it("should insert and retrieve data", () => { db.insert("users", { id: 1, name: "John" }); const user = db.query("SELECT * FROM users WHERE id = 1"); expect(user.name).toBe("John"); }); }); ``` ### beforeAll and afterAll ```typescript import { describe, it, beforeAll, afterAll, expect } from "bun:test"; import { setupExpensiveResource } from "./resources"; describe("Resource-intensive operations", () => { let resource: any; beforeAll(() => { // Setup once for entire suite resource = setupExpensiveResource(); }); afterAll(() => { // Cleanup once after entire suite resource.teardown(); }); it("uses expensive resource", () => { expect(resource.isReady()).toBe(true); }); it("performs operation", () => { const result = resource.process("data"); expect(result).toBeDefined(); }); }); ``` ### Nested Hooks ```typescript import { describe, it, beforeEach } from "bun:test"; describe("Outer suite", () => { let value = 0; beforeEach(() => { value = 10; }); it("test in outer", () => { expect(value).toBe(10); }); describe("Inner suite", () => { beforeEach(() => { value *= 2; // Runs after outer beforeEach }); it("test in inner", () => { expect(value).toBe(20); // 10 * 2 }); }); }); ``` --- ## Mocking with Bun ### Using mock() ```typescript import { mock } from "bun:test"; import { fetchUser } from "./api"; const mockFetch = mock((userId: string) => { return { id: userId, name: "Mock User" }; }); // Test mock behavior const result = mockFetch("123"); expect(result.name).toBe("Mock User"); expect(mockFetch.mock.calls.length).toBe(1); expect(mockFetch.mock.calls[0]).toEqual(["123"]); ``` ### Mock Objects and Modules ```typescript import { describe, it, expect, mock } from "bun:test"; describe("Service with mocked dependency", () => { it("should use mocked database", () => { const mockDb = { query: mock((sql: string) => [{ id: 1, name: "Test" }]), close: mock(() => {}), }; const service = new Service(mockDb); const result = service.getUser(1); expect(result.name).toBe("Test"); expect(mockDb.query.mock.calls.length).toBe(1); }); }); ``` ### Module Mocking ```typescript import { describe, it, expect, mock } from "bun:test"; import { getUserFromAPI } from "./api"; // Mock entire modules mock.module("./api", () => ({ getUserFromAPI: mock((id: string) => ({ id, name: "Mocked User", })), })); describe("API integration", () => { it("should work with mocked API", async () => { const user = await getUserFromAPI("123"); expect(user.name).toBe("Mocked User"); }); }); ``` ### Spy on Function Calls ```typescript import { describe, it, expect, mock } from "bun:test"; describe("Spy on calls", () => { it("should track function calls", () => { const originalFunc = (x: number) => x * 2; const spied = mock(originalFunc); const result1 = spied(5); const result2 = spied(10); expect(result1).toBe(10); expect(result2).toBe(20); expect(spied.mock.calls.length).toBe(2); expect(spied.mock.results[0].value).toBe(10); expect(spied.mock.results[1].value).toBe(20); }); }); ``` ### Mock Return Values
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看