api-testing について
API テスト向けのスキルで、Vitest のコマンドと、ルート、クエリパラメーター、POST リクエスト、依存関係のテスト方法をまとめています。データベース、外部 API、Redis のモックを使う Web API 開発者向けです。
主な機能
- 01Vitest のテストコマンド
- 02ルートと HTTP レスポンスのテスト
- 03クエリパラメーターとエラーのテスト
- 04データベースとサービスのモック
- 05カバレッジ設定のガイド
活用シーン
- 01API ルートのレスポンス検証
- 02無効なクエリパラメーターの確認
- 03POST エンドポイントの動作テスト
- 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 },
},
},
});
参考資料
- Vitest:https://vitest.dev
- Next.js のテスト:https://nextjs.org/docs/app/building-your-application/testing
コメント
Markdown 対応