MSW Mock avec Claude Code
Découvrez mSW Mock avec Claude Code. Conseils pratiques et exemples de code inclus.
MSWでリアルなAPIモック環境を構築する
MSW(Mock Service Worker)はService Workerを利用してネットワークレベルでAPIリクエストをインターセプトするモックライブラリです。テストとブラウザ開発の両方で同じモックハンドラーを共有でき、実際のHTTPリクエストと同じ振る舞いを再現します。Claude Codeはハンドラーの設計から型安全なモック構築まで的確にサポートします。
基本的なハンドラー設計
Claude Codeにハンドラーの構成を依頼しましょう。
> MSWでユーザーAPIのモックハンドラーを設計して。
> CRUD操作、エラーハンドリング、レスポンス遅延を含めて。
import { http, HttpResponse, delay } from "msw";
// インメモリデータベース
let users: User[] = [
{ id: "1", name: "Alice", email: "alice@example.com", role: "admin" },
{ id: "2", name: "Bob", email: "bob@example.com", role: "editor" },
];
export const userHandlers = [
// 一覧取得
http.get("/api/users", async ({ request }) => {
await delay(100);
const url = new URL(request.url);
const page = Number(url.searchParams.get("page") || "1");
const perPage = Number(url.searchParams.get("perPage") || "20");
const search = url.searchParams.get("search") || "";
let filtered = users;
if (search) {
filtered = users.filter(
(u) =>
u.name.toLowerCase().includes(search.toLowerCase()) ||
u.email.toLowerCase().includes(search.toLowerCase())
);
}
const start = (page - 1) * perPage;
const paginated = filtered.slice(start, start + perPage);
return HttpResponse.json({
data: paginated,
meta: { total: filtered.length, page, perPage },
});
}),
// 詳細取得
http.get("/api/users/:id", async ({ params }) => {
await delay(50);
const user = users.find((u) => u.id === params.id);
if (!user) {
return HttpResponse.json(
{ error: "ユーザーが見つかりません" },
{ status: 404 }
);
}
return HttpResponse.json({ data: user });
}),
// 作成
http.post("/api/users", async ({ request }) => {
await delay(200);
const body = (await request.json()) as Omit<User, "id">;
const newUser: User = { ...body, id: String(Date.now()) };
users.push(newUser);
return HttpResponse.json({ data: newUser }, { status: 201 });
}),
// 更新
http.put("/api/users/:id", async ({ params, request }) => {
await delay(150);
const body = (await request.json()) as Partial<User>;
const index = users.findIndex((u) => u.id === params.id);
if (index === -1) {
return HttpResponse.json(
{ error: "ユーザーが見つかりません" },
{ status: 404 }
);
}
users[index] = { ...users[index], ...body };
return HttpResponse.json({ data: users[index] });
}),
// 削除
http.delete("/api/users/:id", async ({ params }) => {
await delay(100);
users = users.filter((u) => u.id !== params.id);
return new HttpResponse(null, { status: 204 });
}),
];
テストでの統合
Vitestとの統合パターンです。
import { setupServer } from "msw/node";
import { userHandlers } from "./handlers/user";
// テスト用サーバー
const server = setupServer(...userHandlers);
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
describe("UserList コンポーネント", () => {
it("ユーザー一覧を表示する", async () => {
render(<UserList />);
await waitFor(() => {
expect(screen.getByText("Alice")).toBeInTheDocument();
expect(screen.getByText("Bob")).toBeInTheDocument();
});
});
it("APIエラー時にエラーメッセージを表示する", async () => {
// テスト単位でハンドラーを上書き
server.use(
http.get("/api/users", () => {
return HttpResponse.json(
{ error: "サーバーエラー" },
{ status: 500 }
);
})
);
render(<UserList />);
await waitFor(() => {
expect(screen.getByText("データの取得に失敗しました")).toBeInTheDocument();
});
});
it("ネットワークエラー時にリトライボタンが表示される", async () => {
server.use(
http.get("/api/users", () => {
return HttpResponse.error();
})
);
render(<UserList />);
await waitFor(() => {
expect(screen.getByRole("button", { name: "再試行" })).toBeInTheDocument();
});
});
});
ブラウザでの開発用モック
ブラウザ環境でService Workerとして動作させるパターンです。
// src/mocks/browser.ts
import { setupWorker } from "msw/browser";
import { userHandlers } from "./handlers/user";
import { authHandlers } from "./handlers/auth";
export const worker = setupWorker(...userHandlers, ...authHandlers);
// src/main.tsx
async function enableMocking() {
if (import.meta.env.DEV) {
const { worker } = await import("./mocks/browser");
return worker.start({
onUnhandledRequest: "bypass",
});
}
}
enableMocking().then(() => {
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
});
型安全なハンドラー設計
TypeScriptの型とMSWハンドラーを統合するパターンです。
import { http, HttpResponse } from "msw";
// API型定義
interface ApiEndpoints {
"GET /api/users": {
response: { data: User[]; meta: PaginationMeta };
params: never;
};
"GET /api/users/:id": {
response: { data: User };
params: { id: string };
};
"POST /api/users": {
response: { data: User };
body: CreateUserInput;
params: never;
};
}
// ファクトリー関数
function createUserFactory(overrides: Partial<User> = {}): User {
return {
id: String(Math.random()).slice(2, 10),
name: `User ${Math.random().toString(36).slice(2, 6)}`,
email: `user-${Date.now()}@example.com`,
role: "viewer",
...overrides,
};
}
// テストシナリオ用のハンドラーセット
export const emptyStateHandlers = [
http.get("/api/users", () =>
HttpResponse.json({ data: [], meta: { total: 0, page: 1, perPage: 20 } })
),
];
export const errorHandlers = [
http.get("/api/users", () =>
HttpResponse.json({ error: "Internal Server Error" }, { status: 500 })
),
];
export const slowResponseHandlers = [
http.get("/api/users", async () => {
await delay(5000);
return HttpResponse.json({ data: [createUserFactory()], meta: { total: 1, page: 1, perPage: 20 } });
}),
];
Summary
MSWはネットワークレベルのモックにより、実際のAPI通信に近い環境でテストと開発ができます。Claude Codeを活用すれば、ハンドラー設計、テスト統合、型安全な構成を短時間で構築可能です。
ユニットテストとの連携はVitest上級テクニックを、E2Eテストでの活用はPlaywright E2Eテスト実践ガイドを参照してください。MSW公式ドキュメントも確認しておきましょう。
Passez votre flux Claude Code au niveau supérieur
50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.
PDF gratuit : aide-mémoire Claude Code en 5 minutes
Commandes clés, raccourcis et exemples de prompts sur une seule page imprimable.
À propos de l'auteur
Masa
Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.
Articles similaires
Créer des commandes slash personnalisées dans Claude Code
Apprenez à créer des commandes slash personnalisées dans Claude Code. Couvre l'emplacement des fichiers, les arguments et l'automatisation des tâches.
10 astuces pour tripler votre productivité avec Claude Code
Découvrez 10 astuces pratiques pour tirer le meilleur parti de Claude Code. Des stratégies de prompts aux raccourcis de workflow, ces techniques amélioreront votre efficacité dès aujourd'hui.
Optimisation Canvas/WebGL avec Claude Code
Découvrez l'optimisation Canvas/WebGL avec Claude Code. Conseils pratiques et exemples de code inclus.