Tips & Tricks

MSW API dengan Claude Code

Pelajari tentang msw api menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.

MSWでリアルなAPImock環境をpembangunan

MSW(Mock Service Worker) Service Worker pemanfaatan ネットワークレベル APIrequest インターセプト mocklibrary.test dan browserpengembangan 両方 同じmockhandler berbagi き、実際 HTTPrequest dan 同じ振る舞い 再現.Claude Code handler 設計 dari type safetyなmockpembangunanま 的確 サポート.

dasar的なhandler設計

Claude Code handler 構成 依頼し.

> MSW dengan penggunaAPI mockhandler 設計して。
> CRUDoperasi、errorハンドリング、response遅延 含めて。
import { http, HttpResponse, delay } from "msw";

// インメモリdatabase
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 = [
  // daftarpengambilan
  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 },
    });
  }),

  // 詳細pengambilan
  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: "pengguna 見つかりません" },
        { status: 404 }
      );
    }
    return HttpResponse.json({ data: user });
  }),

  // pembuatan
  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 });
  }),

  // pembaruan
  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: "pengguna 見つかりません" },
        { status: 404 }
      );
    }
    users[index] = { ...users[index], ...body };
    return HttpResponse.json({ data: users[index] });
  }),

  // penghapusan
  http.delete("/api/users/:id", async ({ params }) => {
    await delay(100);
    users = users.filter((u) => u.id !== params.id);
    return new HttpResponse(null, { status: 204 });
  }),
];

integrasi test

Vitest dan integrasipola.

import { setupServer } from "msw/node";
import { userHandlers } from "./handlers/user";

// test用server
const server = setupServer(...userHandlers);

beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

describe("UserList komponen", () => {
  it("penggunadaftar tampilan", async () => {
    render(<UserList />);

    await waitFor(() => {
      expect(screen.getByText("Alice")).toBeInTheDocument();
      expect(screen.getByText("Bob")).toBeInTheDocument();
    });
  });

  it("APIerror時 errorpesan tampilan", async () => {
    // test単位 handler 上書き
    server.use(
      http.get("/api/users", () => {
        return HttpResponse.json(
          { error: "servererror" },
          { status: 500 }
        );
      })
    );

    render(<UserList />);

    await waitFor(() => {
      expect(screen.getByText("データ pengambilan gagalしま")).toBeInTheDocument();
    });
  });

  it("ネットワークerror時 リトライtombol tampilanされる", async () => {
    server.use(
      http.get("/api/users", () => {
        return HttpResponse.error();
      })
    );

    render(<UserList />);

    await waitFor(() => {
      expect(screen.getByRole("button", { name: "retry" })).toBeInTheDocument();
    });
  });
});

pengembangan用mock browser

browser環境 Service Worker sebagai 動作させるpola.

// 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>
  );
});

type safetyなhandler設計

TypeScript 型 dan MSWhandler integrasi pola.

import { http, HttpResponse } from "msw";

// API型definisi
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;
  };
}

// ファクトリーfungsi
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,
  };
}

// testシナリオ用 handlerセット
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 ネットワークレベル mock より、実際 API通信 近い環境 test dan pengembangan bisa dilakukan.Claude Code pemanfaatanすれば、handler設計、testintegrasi、type safetyな構成 waktu singkat pembangunandimungkinkan.

ユニットtest dan integrasi Vitest上級テクニック 、E2Etest pemanfaatan Playwright E2Etest実践panduan silakan lihat.MSW公式dokumen juga konfirmasi おき.

#Claude Code #MSW #APImock #testing #frontend

Tingkatkan alur kerja Claude Code kamu

50 template prompt yang sudah teruji, siap copy-paste ke Claude Code sekarang juga.

Gratis

PDF Gratis: Cheatsheet Claude Code dalam 5 Menit

Perintah penting, pintasan, dan contoh prompt dalam satu halaman siap cetak.

Unduh PDF
M

Tentang Penulis

Masa

Engineer yang aktif menggunakan Claude Code. Mengelola claudecode-lab.com, media teknologi 10 bahasa dengan lebih dari 2.000 halaman.