关于 api-testing
用于 API 测试的 Skill,介绍 Vitest 命令及路由、查询参数、POST 请求和依赖项的测试方法。面向使用数据库、外部 API 与 Redis 模拟的 Web API 开发者。
主要功能
- 01Vitest 测试命令
- 02路由与 HTTP 响应测试
- 03查询参数及错误测试
- 04数据库与服务模拟
- 05覆盖率配置指南
适用场景
- 01测试 API 路由响应
- 02检查无效查询参数
- 03测试 POST 端点行为
- 04隔离外部服务依赖
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ motormetrics/ motormetrics --skill api-testing安装后在 Claude Code 中输入/api-testing确认已加载。
详细介绍
API 测试技能
运行测试
pnpm test # Run all tests
pnpm test:watch # Watch mode
pnpm test:coverage # With coverage
pnpm -F @sgcarstrends/web test # Run web tests
pnpm -F @sgcarstrends/web test:watch # Watch mode for web
测试结构
apps/web/__tests__/
├── setup.ts # Test setup
├── helpers.ts # Test utilities
├── queries/ # Query tests
├── components/ # Component tests
└── utils/ # Utility tests
测试 API 路由
基本端点测试
import { describe, it, expect } from "vitest";
describe("GET /api/health", () => {
it("returns 200 OK", async () => {
const res = await fetch("http://localhost:3000/api/health");
expect(res.status).toBe(200);
expect(await res.json()).toEqual({ status: "ok" });
});
});
使用查询参数进行测试
describe("GET /api/cars", () => {
it("filters by month", async () => {
const res = await fetch("http://localhost:3000/api/cars?month=2024-01");
expect(res.status).toBe(200);
});
it("returns 400 for invalid month", async () => {
const res = await fetch("http://localhost:3000/api/cars?month=invalid");
expect(res.status).toBe(400);
});
});
测试 POST 端点
describe("POST /api/posts", () => {
it("creates a new post", async () => {
const res = await fetch("http://localhost:3000/api/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Test", content: "Content" }),
});
expect(res.status).toBe(201);
});
});
模拟
模拟数据库
import { vi } from "vitest";
import { db } from "../src/config/database";
vi.spyOn(db.query.cars, "findMany").mockResolvedValue([
{ make: "Toyota", model: "Corolla", number: 100 },
]);
模拟外部 API
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: async () => ({ records: [] }),
});
global.fetch = mockFetch;
模拟 Redis
vi.mock("@sgcarstrends/utils", () => ({
redis: {
get: vi.fn(),
set: vi.fn(),
del: vi.fn(),
},
}));
测试辅助工具
// apps/web/__tests__/helpers.ts
export const createAuthHeader = (token: string) => ({
Authorization: `Bearer ${token}`,
});
export const seedDatabase = async (data: any[]) => {
await db.insert(cars).values(data);
};
export const clearDatabase = async () => {
await db.delete(cars);
};
最佳实践
- 隔离测试 - 每个测试都应相互独立
- 测试错误情况 - 测试正常路径和错误路径
- 使用模拟对象 - 模拟外部依赖
- 清理 - 在 afterEach 中重置状态
- 使用描述性名称 - 编写清晰的测试描述
- 覆盖率目标 - 目标覆盖率为 80% 以上
覆盖率配置
// vitest.config.ts
export default defineConfig({
test: {
coverage: {
provider: "v8",
thresholds: { lines: 80, functions: 80, branches: 80 },
},
},
});
参考资料
评论
支持 Markdown