React에서 MSW 2.0 적용, 동적 경로 및 쿼리스트링을 받을 경우 핸들러 파일 수정하기
Mock Service Worker(MSW)는 웹 개발 및 테스트 환경에서 네트워크 요청을 모킹(mocking)하고, 가짜 응답을 제공하여 서버와의 상호작용을 시뮬레이션하는 도구입니다. 이 도구는 특히 API 호출을 테스트할 때 매우 유용하며, 서버가 실제로 존재하지 않거나 서버에 접근할 수 없는 경우에도 클라이언트 애플리케이션을 개발하고 디버깅할 수 있게 해줍니다.
MSW 2.0 버전 설치하기
dev 환경에서만 작동하도록 --save-dev
옵션을 붙여 msw
를 설치합니다.
npm install msw --save-dev
서비스워커 파일 생성하기
아래 명령어를 입력하여 서비스워커 파일을 생성해줍니다.
npx msw init public/ --save
파일 생성하기
핸들러, 브라우저 설정 파일을 생성합니다.
src/mocks/browser.js
import { setupWorker } from 'msw/browser';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);
src/mocks/handlers.js
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('https://test.dev/todos/1', () => {
return HttpResponse.json([
{
id: 1,
name: 'Shopping',
},
]);
}),
];
서비스워커 시작
서비스워커를 시작하기 위해 index.js 파일을 수정해줍니다.
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
async function enableMocking() {
if (process.env.NODE_ENV !== 'development') {
return;
}
const { worker } = await import('./mocks/browser');
return worker.start();
}
enableMocking().then(() => {
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
});
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
Mock 데이터 호출하기
이제 주소를 호출하면 실제 응답을 받는 것처럼 Mock 데이터를 사용할 수 있습니다.
src/App.js
import { useEffect } from 'react';
function App() {
const init = async () => {
const res = await fetch('https://test.dev/todos/1');
const data = await res.json();
console.log(data);
};
useEffect(() => {
init();
}, []);
return <></>;
}
export default App;
핸들러 파일 수정하기
path 값이 동적으로 바뀌는 경우와 쿼리스트링에 따라서 동적으로 값이 변할 때의 핸들러 예시입니다.
// 쿼리스트링을 식별해야될 경우
http.get('https://test.dev/todos', ({ request }) => {
const url = new URL(request.url);
const status = url.searchParams.get('status');
const perPage = url.searchParams.get('perPage');
return HttpResponse.json(todoData[status].slice(0, perPage));
}),
// 동적 경로를 가질 경우
http.get('https://test.dev/todos/:id', ({ params }) => {
const { id } = params;
return HttpResponse.json(allTodoData[id]);
}),