전에 프로젝트를 할때 팀원이 MSW를 쓰자하여 따라해보긴 했었다.
MSW를 써보니 express로 Mock 서버를 만드는것보다 간단하고 편리했다.
그래서 이번 사이드프로젝트를 하며 MSW를 써보기로 하였다.
MSW는 서비스 워커(Service Worker)를 사용하여 네트워크 호출을 가로채는 API 모킹(mocking) 라이브러리이다.
즉, 브라우저에서 마치 백엔드 API인 척하여 프론트엔드의 요청에 가짜 데이터를 응답해주는 녀석이다.
백엔드 API 개발과 프론트엔드 개발이 동시에 진행돼야하는데, 백엔드 API 구현이 완료전까지 프론트엔드에서 데이터요청을 Mock 데이터를 활용하여 MSW로 가짜 응답을 받아가며 테스트를 해보기 위함이다!
그리고 무엇보다 써보고 싶었다.
브라우저 Request flow diagram
1. 브라우저에서 요청을 보내면
2. 서비스워커가 받아
3. 요청을 클론하여
4. MSW로 보내고
5. 모킹한값(응답)을 다시 서비스워커로 보내고
6. 서비스워커는 전달 받은 응답을 브라우저로 보내준다.
서비스워커는 브라우저 환경이 아닌곳에서는 동작하지 않음!
노드에서는 노드서버 방식을 사용한다.
설치 및 세팅
npm install msw --save-dev
msw를 먼저 설치 해준 뒤 ->
public 폴더에 mockServiceWorker 파일을 생성해주는 명령어까지 실행!
npx msw init public/ --save
이번프로젝트는 Next.js + typescript를 적용시킨 프로젝트이다.
app.tsx
//worker를 실행 시켜주는 코드 추가
if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
import('../mocks');
}
.env
NEXT_PUBLIC_API_MOCKING
라는 환경변수를 사용하게 되는데 이 환경변수에 따라 mock 서버를 사용 할지를 결정하기 때문에 .env 파일같은 환경변수 파일에 해당 환경변수를 추가해 준다.NEXT_PUBLIC_API_MOCKING=enabled
mocks
mocks 폴더 아래에 파일들을 세팅한다.
mocks/browser.ts
import { setupWorker } from 'msw';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);
mocks/handlers.ts
아래 handlers.ts에는 내가 현재 사용중인 api 모킹 코드를 써보았다.
import {rest} from 'msw';
interface UserInfo {
email?: string;
password?: string;
nickname?: string;
}
export const handlers = [
rest.get<UserInfo>('/api/members', (req, res, ctx) => {
const searchParam = new URLSearchParams(req.url.searchParams);
const email = searchParam.get('email');
const existEmail = MockUsers.find((el) => {
return email === el.email;
});
if (email && existEmail) {
return res(
ctx.delay(),
ctx.status(400),
ctx.json('중복된 이메일 입니다.'),
);
} else if (email && !existEmail) {
return res(
ctx.delay(),
ctx.status(200),
ctx.json('사용가능한 이메일 입니다.'),
);
} else {
return res(ctx.delay(), ctx.status(200), ctx.json('아무것도 안씀!'));
}
}),
]
mocks/index.ts
if (typeof window === 'undefined') {
const { server } = require('./server');
server.listen();
} else {
const { worker } = require('./browser');
worker.start();
}
export {};
mocks/server.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
이렇게 설치 & 세팅해두고 handlers.ts에 쓰고 싶은 모킹 코드를 써가며 활용하면 끝!