안녕하세요. J4J입니다.
이번 포스팅은 MSW API Mocking 하기 두 번째인 Browser 환경에서 사용하는 방법에 대해 적어보는 시간을 가져보려고 합니다.
이전 글
[React] MSW로 API Mocking 하기 (1) - MSW란?
Browser 환경이란?
MSW에서는 Browser, Node 총 2개의 환경을 제공해 줍니다.
여기서 Browser 환경은 말 그대로 Browser에 접속했을 때 발생되는 API 처리를 Mocking 해주는 것을 의미합니다.
쉽게 접근할 수 있는 것은 React를 이용하여 서버를 실행한 뒤 브라우저를 통해 실행된 서버에서 접속했을 때 요청되는 API들을 Mocking 해준다고 생각하면 됩니다.
Browser 환경에서 MSW를 사용하게 되면 실제 API가 개발이 되지 않았거나 또는 로컬 환경에서 API 호출에 대한 테스트를 진행할 때 원활하게 수행할 수 있도록 도와줍니다.
또한 실제 호출되어야 하는 API 관련 소스 코드의 변경 없이도 브라우저 환경에서 문제없이 동작하기 때문에 효과적으로 여러 상황에서 테스트하기에 적합하다고 말할 수 있습니다.
설정 방법
[ 1. public directory에 msw 초기 설정 ]
$ npx msw init {public directory} --save // ex) npx msw init public/ --save
해당 설정은 public 경로를 기반으로 msw에서 자체적으로 설정을 진행해 줍니다.
정상적으로 실행이 된다면 public 경로 아래에 mockServiceWorker.js 파일이 생성된 것을 확인할 수 있습니다.
[ 2. 패키지 설치 ]
$ npm install -D msw
[ 3. handler 및 worker 설정 ]
먼저 handler에는 특정 API 호출을 하게 될 경우 어떤 결괏값을 전달해 줄지에 대한 mocking 처리를 정의해 주면 됩니다.
예를 들어 사람들의 이름들을 조회하는 API를 호출하게 된다면 다음과 같이 handler를 정의해 줄 수 있습니다.
// src/mocks/handlers/person-handler.ts
import { rest } from 'msw';
export const personHandlers = [
// GET method인 /get-names를 호출하면 다음과 같이 response가 되도록 mocking 정의
rest.get('/get-names', (req, res, ctx) => {
const names = ['jimi', 'john', 'scott', 'queen']
return res(
ctx.status(200),
ctx.json(names),
)
})
]
// src/mocks/handlers/index.ts
import { personHandlers } from "./person-handler";
// 여러 handler를 한 곳에 묶어서 return
export const handlers = [
...personHandlers
]
handler 정의가 끝났다면 handler를 활용하여 msw의 worker 설정을 다음과 같이 해줄 수 있습니다.
// src/mocks/browser.ts
import { setupWorker } from "msw";
import { handlers } from "./handlers";
export const worker = setupWorker(...handlers);
[ 4. worker 등록 ]
일반적으로 msw를 사용하는 경우는 운영 환경에서 동작될 수도 있지만 거의 그럴 경우는 없을 것이고 대부분 로컬 환경이나 개발 환경이 될 것입니다.
그래서 index 파일 또는 main 파일에 다음과 같이 환경이 맞을 때만 msw가 동작될 수 있도록 위에서 정의한 worker를 등록해 주시면 됩니다.
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { worker } from "./mocks/browser";
if(process.env.NODE_ENV === 'development') { // 개발에서만 msw 동작
worker.start();
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
테스트
위에서 설정한 API를 호출해 보는 테스트 페이지를 다음과 같이 만들어 보겠습니다.
import axios from "axios";
import { useEffect, useState } from "react";
export default function App() {
const [personNames, setPersonNames] = useState<string[]>([]);
async function apiGetNames() {
const res = await axios.get('/get-names');
if(res.data) {
setPersonNames(res.data);
}
}
useEffect(() => {
apiGetNames();
}, [])
return (
<div>
<div>
<h2>사람들의 이름을 호출해보겠습니다 !</h2>
</div>
<div>
{personNames.map((personName, index) => (
<p key={personName}>{index+1}번째 이름은 {personName}입니다.</p>
))}
</div>
</div>
)
}
그리고 서버를 실행하여 브라우저에 접속해 보면 다음과 같이 msw에 의해 mocking 된 API가 전달된 것을 확인할 수 있고, console 창에서 msw에 의해 API가 호출된 것도 볼 수 있습니다.
상황 별 다른 Mocking 처리 (Override)
위의 설정을 생각해 보면 /get-names에 대한 API 호출의 mocking 처리는 개발 환경에서 어느 페이지든 동일한 결과를 불러옵니다.
하지만 개발을 하다 보면 아무리 mocking 처리를 하더라도 상황에 따라 다른 결과를 받을 수 있는 상황이 발생될 수 있습니다.
이런 상황들이 생길 경우 다음과 같이 override를 수행하여 페이지마다 다른 결과를 만들어 주시면 됩니다.
[ 1. 페이지에 override handler 정의 ]
위에서 작성한 소스 코드에서 페이지 쪽만 다음과 같이 변경해 볼 수 있습니다.
import axios from "axios";
import { rest } from "msw";
import { useEffect, useState } from "react";
import { worker } from "./mocks/browser";
export default function App() {
const [personNames, setPersonNames] = useState<string[]>([]);
function mswConfig() {
worker.use(
// GET method인 /get-names를 해당 페이지에서만 따로 활용
rest.get('/get-names', (req, res, ctx) => {
const names = ['app-jimi', 'app-john', 'app-scott', 'app-queen']
return res(
ctx.status(200),
ctx.json(names),
)
})
)
}
async function apiGetNames() {
const res = await axios.get('/get-names');
if(res.data) {
setPersonNames(res.data);
}
}
useEffect(() => {
mswConfig();
apiGetNames();
}, [])
return (
<div>
<div>
<h2>사람들의 이름을 호출해보겠습니다 !</h2>
</div>
<div>
{personNames.map((personName, index) => (
<p key={personName}>{index+1}번째 이름은 {personName}입니다.</p>
))}
</div>
</div>
)
}
[ 2. 테스트 ]
코드를 위와 같이 수정하고 다시 브라우저에 접속해 보면 동일한 페이지임에도 불구하고 이전과 다른 API response 값을 확인할 수 있습니다.
이상으로 MSW API Mocking 하기 두 번째인 Browser 환경에서 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'SPA > React' 카테고리의 다른 글
[React] MSW로 API Mocking 하기 (4) - Storybook에서 사용하기 (1) | 2023.10.16 |
---|---|
[React] MSW로 API Mocking 하기 (3) - Node 환경에서 사용하기 (0) | 2023.10.11 |
[React] MSW로 API Mocking 하기 (1) - MSW란? (0) | 2023.10.08 |
[React] Vite 타입 스크립트 프로젝트에 Jest 사용 환경 설정 (4) | 2023.10.06 |
[React] Jest로 테스트할 때 비동기 처리하기 (0) | 2023.10.05 |
댓글