이번 글에서는 마저 이어서 MSW 설치부터 적용, 그리고 잘 사용했는지(?)에 대해 기술해 보려고 합니다.
우선 MSW를 사용하려면 패키지를 먼저 설치해줘야겠죠?
MSW 패키지 설치
npm install msw --save-dev
# or
yarn add -D msw
폴더 구조
이거는 팀바팀, 사람마다 다르겠지만 저는 src 폴더 내에 mocks 라는 폴더를 생성해줬습니다.
그리고, mocks 폴더 내에 handlers.ts라는 파일을 만들어주고 아래와 같은 코드를 넣어줬는데요, 자세한 설명은 주석으로 달겠습니다!
// src/mocks/handlers.ts
import { http, HttpResponse } from "msw";
import { SignUpFormData } from "../lib/schema/auth.schema";
export const registerHandlers = [
http.post("/api/register", async ({ request }) => {
const { account, password, passwordCheck, name, studentId, grade } =
(await request.json()) as SignUpFormData;
// 아이디가 'blockedId'면 가입 불가 처리
if (account === "blockedId") {
return HttpResponse.json(
{ success: false, message: "사용할 수 없는 아이디입니다." },
{ status: 400 }
);
}
// 비밀번호 불일치 처리
if (password !== passwordCheck) {
return HttpResponse.json(
{ success: false, message: "비밀번호 확인이 일치하지 않습니다." },
{ status: 400 }
);
}
// 정상 응답 반환
return HttpResponse.json(
{
success: true,
message: "회원가입이 완료되었습니다!",
data: { account, name, studentId, grade },
},
{ status: 200 }
);
}),
];
주의해야 할 점으로는 기존 0.x.x 버전에서는 import { rest } from "msw"를 사용했지만
1.x.x 버전 이상에서는 import { http } from "msw" 을 사용합니다.
또, res, req, ctx 대신 request를 사용합니다.
handler 동작 개요
- POST /api/register 요청을 가로챕니다.
- account 값이 "blockedId"이면 400 응답 반환 → "사용할 수 없는 아이디"
- password와 passwordCheck가 다르면 400 응답 반환 → "비밀번호 확인이 일치하지 않음"
- 위 조건이 통과되면 회원가입 성공 응답 반환 (200)
이제 다음부터는 굉장히 쉬운데요, 회원가입 페이지만 제외하면 코드 그대로 옮겼습니다!
mocks 폴더 내에 index.ts 파일을 추가하구 저같은 경우엔 browser.ts 파일 내용을 index.ts 내부에 옮겼습니다.
mocks/browser.ts - MSW 서비스 워커 등록
// src/mocks/browser.ts
import { setupWorker } from "msw/browser";
import { registerHandlers } from "./handlers";
// 서비스 워커 설정
export const worker = setupWorker(...registerHandlers);
mocks/index.ts - 개발 환경에서만 MSW 실행
// src/mocks/index.ts
import { setupWorker } from "msw/browser";
import { registerHandlers } from "./handlers";
export const initMockServer = () => {
if (process.env.NODE_ENV === "development") {
const worker = setupWorker(...registerHandlers);
worker.start({
onUnhandledRequest: "bypass", // 등록되지 않은 요청은 그대로 서버로 전달
});
}
};
main.tsx - 애플리케이션 초기화 시 MSW 실행
// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
import "./index.css";
// MSW 초기화
import { initMockServer } from "./mocks";
if (process.env.NODE_ENV === "development") {
initMockServer();
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>
);
RegisterStep.tsx - 회원가입 폼 컴포넌트
import React from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "sonner";
import { signUpSchema, SignUpFormData } from "../../lib/schema/auth.schema";
import { useNavigate } from "react-router-dom";
export default function RegisterStep3() {
const navigate = useNavigate();
const {
register,
handleSubmit,
formState: { errors },
} = useForm<SignUpFormData>({
resolver: zodResolver(signUpSchema),
defaultValues: {
account: "",
password: "",
passwordCheck: "",
name: "",
studentId: "",
grade: 1,
},
});
// 회원가입 폼 제출
const onSubmit = async (data: SignUpFormData) => {
try {
console.log("전송 데이터:", data);
const response = await fetch("/api/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
console.log("응답 상태:", response.status);
const result = await response.json();
console.log("MSW 응답:", result);
toast.success("회원가입 완료되었습니다!");
navigate("/login");
} catch (error) {
console.error("회원가입 오류:", error);
toast.error("회원가입 중 오류가 발생했습니다.");
}
};
응답 성공 시 console.log
이슈
- .env 파일에 NODE_ENV=development 설정 후 콘솔에 [MSW] Mocking enabled. 가 떠야하는데 안뜸
- 이런 경우엔 public 폴더 내에 mockServiceWorker.js 파일이 존재하지 않아서인데, 아래 명령어를 터미널에 입력하면 생성됩니다.
- npx msw init public/
- POST http://localhost:3000/api/register 404 (Not Found)
SyntaxError: Failed to execute 'json' on 'Response': Unexpected end of JSON input- 이런 에러가 뜰 수도 있는데 해당 오류는 MSW가 요청을 가로채지 않고, 실제 Dev 서버(혹은 없는 서버)로 요청이 가서 404 Not Found가 뜨는 전형적인 상황이에요.
즉, 서비스 워커가 정상적으로 등록/작동하지 않거나, 핸들러가 제대로 매칭되지 않는 경우입니다. - 따라서 mocking 한 api 주소가 일치한지 잘 확인해야 합니다.
- 이런 에러가 뜰 수도 있는데 해당 오류는 MSW가 요청을 가로채지 않고, 실제 Dev 서버(혹은 없는 서버)로 요청이 가서 404 Not Found가 뜨는 전형적인 상황이에요.
마무리
사실 MSW를 시도한 것이 이번이 두 번째인데요, 이전에 시도를 한 번 했었다가 시간이 없었기도 했고 잘 몰랐어서 실패를 했는데 공식문서와 GPT (사실 claude가 더 좋은 거 같긴 합니다만..)를 적절히 잘 이용해서 해결했습니다.
사용해보면서 느낀 점이지만 API가 아직 나오지 않았을 때 정말 사용하기 좋겠다라는 생각이 많이 들었구요, 다른 mocking 관련 라이브러리가 있지만 MSW도 사용하는데 어려움이 없는 것 같습니다.
제가 써놓은 최신 버전을 이용할 때와 구 버전과의 차이점 같은 주의할 점만 유의하신다면 구현하는데는 크게 어려움이 없을 것 같아요.
코드가 좀 많아서 가독성이 좋지 않다면 심심한 사과의 말씀을 남기면서 글을 이만 마쳐보도록 하겠습니다.
지금까지 읽어주셔서 감사합니다 :)
Reference
공식 문서 : https://mswjs.io/
Mock Service Worker
API mocking library for browser and Node.js
mswjs.io
'MSW (Mocking Service Worker)' 카테고리의 다른 글
MSW (Mocking Service Worker)로 죽은 프로젝트 그나마(?) 언데드로 만들기 (1) (0) | 2025.03.05 |
---|