💻 Frontend

[FE] mock server with msw

date
May 26, 2023
slug
fe-mock-server-with-msw
author
status
Public
tags
Next.js
Frontend
summary
퍼블리싱 단계에서 로딩, 실패 상태를 테스트하기 위해 프론트 mock 서버 만들기
type
Post
thumbnail
스크린샷 2023-05-26 오전 10.12.34.png
category
💻 Frontend
updatedAt
Apr 16, 2024 02:44 AM

A. msw

0. When?

  • SW Model: FE 개발이 Server 개발보다 선행될 시
  • Debugging: mock 데이터를 실제 API 연결을 가정하여 테스트

1. Overview

├─ public │ ├─ mockServiceWorker.js ├─ src // 프로젝트 소스코드 시작 ├─ app.mocks │ ├─ server.ts │ ├─ userHandler.ts │ ├─ teamHandler.ts ├─ app.hooks │ ├─ useQueryFn.ts ├─ app.modules │ ├─ api │- pages │ ├─ _app.js.

2. Init Setting

// add library to devDependencies npm install -D msw // init service worker code in public repo.(/public에 mockServiceWorker.js 생성) msw init public/ --save

3. Worker

  • 가로챌 Server를 세팅하는 파일
  • app.mocks 폴더를 만들어준 후, server.ts 파일을 만든다.
  • SSR(Next.js)에 대응할 수 있도록 setupServer 사용
import { setupServer } from 'msw/node'; export const worker = setupServer( ...userHandler, ...teamHandler, ...reportHandler // Handler를 서버 세팅에 추가해준다. );
  • msw는 백엔드 측 서버 연결 작업이 진행되지 않았을 때, 수행해볼 수 있으므로 FE 측 테스트 서버에 적용
  • _app.js에 다음 코드를 추가해준다.
    • if (processEnvApp === 'development'){ worker.listen(); // msw 서버 구독 시작 }

4. Handler

a. How?

  • app.modules > msw 폴더 하위에 기능별로 파일을 만든다.
    • {기능명}Handler.ts
const tempData: object[]; // mock 객체 배열 데이터 export const userHandler = [ rest.post(path, resolver), ..., rest.get(path, (req, res, ctx) => { // request에 data를 보내줄 때 필요 const userId = req.url.searchParams.get('userId'); // 필요에 따라 json 리턴 return res( ctx.status(200), // status code 지정 ctx.json(tempData) // 생성해둔 mock 데이터에 조건(userId)에 따라 다양한 처리 가능 ); }), ]
  • rest 함수는 REST API request를 수행하는 함수
    • get(), post(), put(), delete() 등의 메소드를 가짐
  • 각 메소드는 path, resolver를 인자로 가짐
    • path: API url 부분
    • resolver: (request, response, context) ⇒ {}
      • req: 리퀘스트된 정보를 담고 있음
      • res: return하게 되는 정보
      • ctx: res의 인자에 사용
        • ctx.delay: 딜레이 시간(ms) 설정 가능
        • ctx.status: status code 지정
        • ctx.json: json 타입 리턴

b. RESTful API: Path with Parameter

  • FE - When? : url 부분을 함수형으로 사용
    • ex) API_USER_DETAIL = (userId) => `/user/detail/${userId}`
  • msw - How?
    • path: user/detail/:userId 로 설정
    • resolver: parsed된 파라미터는 아래와 같이 접근 가능
    • const { userId } = req.params;
    • ctx.json(): 내부의 인자를 find 혹은 filter 함수를 사용해 mock 객체 배열에서 필요한 데이터만을 접근

c. RESTful API: Query-string with Parameter

  • FE - When? : useQueryFn 사용시 data가 존재할 때
    • ex) useQueryFn([url, {data}], options)
  • msw - How?
    • path: url과 동일하게 설정
    • resolver
      • 1) single parameter로만 구성될 때 ex) ?code=abcdefg&number=1234
      • const type = req.url.searchParams.get('type');
      • const number = req.url.searchParams.get('number');
      • 2) multiple parameters
      • const ids = req.url.searchParams.getAll('id');

5. Debug

  • react-query 툴에서 기존과 동일하게 확인 가능
  • 개발자 도구 Network 탭에서는 확인되지 않는 것으로 보임