2023. 2. 3. 19:45ㆍFE/JavaScript
네트워크 레벨에서 요청을 가로채서 API 요청에 대한 응답을 할 수 있다.
Mock Service Worker 설치하기
npm install msw --save-dev
Mocks 정의하기
모의 요청을 정의하기 위해 request handler 함수를 사용한다.
이를 통해 메서드, URL 등을 기반으로 모든 요청을 캡처하고 반환할 응답을 지정할 수 있다.
request handler 목록, 브라우저 및 서버별 설정을 mock definition이라 불린다.
API 모킹 관련 모듈을 단일 디렉토리에서 보관하는 것을 권장한다.
mkdir src/mocks
mocks 디렉토리가 있다면, request handler가 있을 모듈을 만든다.
touch src/mocks/handlers.js
API 선택하기
MSW로 API를 모킹하는 방식은 실제 애플리케이션에서 API가 사용되는 방식과 유사하다.
REST API
GraphQL API
Mocking REST API
Imports
src/mocks/handlers.js 파일에서 REST API를 모킹을 위해 필요한 것들을 가져온다.
msw 라이브러리에서 rest namespace로 그룹화 되어 있다.
import { rest } from "msw";
Request handler
REST API를 처리하려면, 메소드, 경로, 모의 응답을 반환할 함수가 필요하다.
기본적인 로그인 플로우를 모킹해보자
POST / login : 유저 로그인 가능하도록 하는 API
GET / user : 로그인한 유저에 대한 정보 반환하는 API
rest 메소드를 호출하고 경로를 설정하면 request handler를 만들 수 있다.
import { rest } from "msw";
export const handlers = [
rest.post("/login", null),
rest.get("/user", null),
]
Response resolver
가로챈 요청에 응답하려면, response resolver 함수를 사용해서 모의 응답을 명시해야 한다.
response resolver는 다음 인자들을 갖는 함수다.
req : 요청에 대한 정보
res : 모의 응답을 만들기 위한 유틸리티
ctx : 모의 응답의 상태 코드, 헤더, 바디 등을 설정하는데 사용되는 함수들의 그룹
request handler에게 response resolver를 전달한다.
import { rest } from "msw";
export const handlers = [
rest.post("/login", (req, res, ctx) => {
sessionStorage.setItem("is-authenticated", "true");
return res(ctx.status(200));
}),
rest.get("/user", (req, res, ctx) => {
const isAuthenticated = sessionStorage.getItem("is-authenticated");
if (!isAuthenticated) {
return res(
ctx.status(403),
ctx.json({
errorMessage: "Not authorized",
})
);
}
return res(
ctx.status(200),
ctx.json({
username: "admin",
})
);
}),
];
Integrate
동일한 request handler는 브라우저와 노드 환경 간에 공유될 수 있다.
Service Worker가 노드에서 실행될 수 없기 때문에, 환경에 따라 통합 프로세스가 다르다.
Broswer
Node
Broswer에서 모의 실행하기
msw 설치하기
Service Worker를 등록하여 클라이언트 단에서 MSW는 작동한다.
하지만 라이브러리에서 배포하는 Worker 파일을 복사해야 한다.
MSW는 이를 도와주는 전용 CLI를 제공한다.
MSW CLI 명령어 init를 실행한다.
npx msw init <PUBLIC_DIR> --save
PUBLIC_DIR에 서버의 public 디렉토리 상대 경로를 작성하면 된다.
이렇게 --save 옵션을 사용해서 package.json에 public 디렉토리를 저장한다.
Configure Worker
Service Worker를 구성하고 시작할 mock definition 디렉토리에 파일을 만든다.
touch src/mocks/browser.js
browser.js 파일에서 worker 인스턴스를 만든다.
setupWorker 함수를 임포트하고 이전에 정의한 request 핸들러로 워커 인스턴스를 생성한다.
import { setupWorker } from "msw";
import { handlers } from "./handlers";
export const worker = setupWorker(...handlers);
Start worker
런타임에 mock definition을 실행하기 위해, 애플리케이션에 임포트 되어 있어야 한다.
모킹은 개발 지향적인 기술이기 때문에 src/mocks/browser.js 파일에 임포트 한다.
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
if (process.env.NODE_ENV === "development") {
const { worker } = require("./mocks/browser");
worker.start();
}
ReactDOM.render(<App />, document.getElementById("root"));
worker 시작은 비동기 작업이라 마운트 시점에 요청하는 애플리케이션에 경쟁 조건을 만들 수 있다.
만약 이런 경우, worker가 준비 되었을 때, 애플리케이션이 마운트하도록 defferred mounting에 대해 참고하기!
Verify & Inspect
mock definition 임포트 이후에 브라우저 콘솔에서 MSW 활성화 메시지를 볼 수 있다.
이제 정의한 핸들러와 매치되는 요청들은 가로채 모킹될 것이다.
'FE > JavaScript' 카테고리의 다른 글
[JavaScript] 이벤트 바인딩 (0) | 2023.02.07 |
---|---|
[JavaScript] Blocking, Non-blocking, Sync, Async 이해하기 (0) | 2023.02.07 |
[JavaScript] 자바스크립트에서 비동기 작업은 어떻게 동작할까? (0) | 2023.02.01 |
[Javascript] 함수와 일급 객체 (0) | 2022.10.24 |
[Javascript] 생성자 함수에 의한 객체 생성 (0) | 2022.10.23 |