[MSW] Mock Service Worker 사용 하기

LMH·2023년 3월 16일
0

프로젝트 중에 클라이언트 코드를 테스트할 때, 서버가 구축되어 있지 않을 때 더미 데이터를 이용해서 테스틀르 진행하고는 합니다. Firebase와 같은 실시간 데이터베이스를 사용해도 데이터 통신이 가능하지만 Mock Service Worker 라이브러리를 이용하면 라이브러리로,서버를 향한 네트워크 요청을 가로채서(intercept) 모의 응답(mocked response)을 내려주는 역할을 합니다.

MSW의 동작원리는 브라우저에 서비스 워커(Service Woker)를 등록하여 fetch 이벤트를 사용해 외부로 나가는 요청을 감지하고 그 요청을 실제 서버가 아닌 MSW 클라이언트 사이드 라이브러리로 보낸 후 등록된 핸들러를 통해 모의 응답을 브라우저로 보내는 것 입니다.

MSW는 REST API와 GraphQl API 모두 지원하고 있지만, 이 포스팅에서는 REST API 대한 내용을 정리 해보겠습니다.

설치

msw를 설치하고 디렉토리와 js 파일을 만들어 줍니다.

npm install msw --save-dev

mkdir src/mocks

touch src/mocks/handlers.js

REST API

rest 객체를 불러와 HTTP 메소드별로 로직을 작성할 수 있습니다. 아래의 예제 코드에서는 handlers라는 배열에 각 요청과 응답에 대한 로직을 추가합니다. 코드 양식은 Node.Js의 서버 사이드 코드와 비슷합니다.

import { rest } from 'msw'
export const handlers = [
  rest.post('/login', (req, res, ctx) => {
    // Persist user's authentication in the session
    sessionStorage.setItem('is-authenticated', 'true')
    return res(
      // Respond with a 200 status code
      ctx.status(200),
    )
  }),
  rest.get('/user', (req, res, ctx) => {
    // Check if the user is authenticated in this session
    const isAuthenticated = sessionStorage.getItem('is-authenticated')
    if (!isAuthenticated) {
      // If not authenticated, respond with a 403 error
      return res(
        ctx.status(403),
        ctx.json({
          errorMessage: 'Not authorized',
        }),
      )
    }
    // If authenticated, return a mocked user details
    return res(
      ctx.status(200),
      ctx.json({
        username: 'admin',
      }),
    )
  }),
]

브라우저에서 서비스 워커 등록

브라우저에서 사용하기 위해서는 MSW를 서비스 워커에 등록하는 과정이 필요합니다. 편리하게도 커맨드 라인에서 아래의 명령어를 실행하면 서비스 워커 등록을 위한 파일이 public 폴더에 추가됩니다.

npx msw init <PUBLIC_DIR> --save

개발 환경에 따라 public 폴더의 사용의 설정든 다음과 같이 지정되어 있습니다. 여기서 public 폴더는 웹 서버가 호스팅하는 폴더를 의미합니다.

핸들러를 서버에 등록합니다.

touch src/mocks/browser.js
// src/mocks/browser.js
import { setupWorker } from 'msw' // node 환경에서는 setupServer 모듈을 대신 사용
import * as handlers from './handlers'
export const worker = setupServer(...handlers)
// src/index.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'))

Reference

https://mswjs.io/
https://blog.rhostem.com/posts/2021-03-20-mock-service-worker

profile
새로운 것을 기록하고 복습하는 공간입니다.

0개의 댓글