0. MSW 공부 계기

  • 취뽀스테이션(졸업작품)을 개발할 땐 firebase를 이용해 개발을 진행했기 때문에 MSW를 이용하고싶어도 굳이 ? 싶은 생각이 들었었다.
  • 그러나 이번 세론 프로젝트를 진행하며 MSW가 필요할 것 같아 공부하게 되었다.

1. Mocking REST API

동작원리

1.1 기본 설정

  • React 프로젝트 설치 및 msw 설치
yarn create vite msw_study --template-react-ts
cd msw_study
yarn 
yarn add msw --dev
yarn run dev

1.2 Mock Definition

  • src폴더 안에 mocks 폴더 만들기
  • mocks 폴더 안에 handler.js 파일 만들기

1.3 API 고르기

  • 보통 REST API를 사용하므로 REST API로 가자
  • 공식문서에서도 고민되면 REST API 쓰라고 나와있음

1.4 Request handler

  • 우리가 REST API request를 다루고 싶으면 그에 대한 method, path 그리고 mocking할 response를 반환하는 함수를 정해주어야한다.
  • 이 튜토리얼에서는 우리는 유저의 로그인 흐름을 모킹할 것이다.
    • POST/login : 유저가 로그인 가능하도록 하는 것
    • GET/user : 로그인된 유저의 정보를 리턴하는 것
    • // src/mocks/handlers.js import { rest } from 'msw' export const handlers = [ // Handles a POST /login request rest.post('/login', /*response resolver*/), // Handles a GET /user request rest.get('/user', /*response resolver*/), ]

1.5 Response resolver

위에서 request handler를 작성하였는데, rest.post('/login', **여기**)**,** 이 코드에 여기 부분에는 req, res, ctx를 인자로 갖는 response resolver 콜백함수가 들어가야 한다.

  • req : 서버로 요청이 전송되다 붙잡힌 request
  • res : 모킹된 response
  • ctx : 모킹된 response의 status code, headers, body 등
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 isAuth = sessionStorage.getItem('is-authenticated');
        if(!isAuth){
            return res(
                ctx.status(403),
                ctx.json({
                    errorMessage : "Not Authorized",
                })    
            )    
        }    
        return res(
            ctx.status(200),
            ctx.json({
                usename: 'admin',
            })
        )

    })
] 
  • HTTP POST 요청 처리를 위해 rest.post 함수를 사용하여 요청을 보낸다.
  • 핸들러 함수의 첫 번째 파라미터로 ‘/login’ 이라는 요청 경로를 넣었고, 두 번째 파라미터로는 response resolver라는 콜백함수를 넣어주었다.
  • response resolver 함수는 res, req, ctx를 인자로 갖는다.
  • req, res, ctx를 사용하여 원하는 조건에 따라 모의 응답을 작성한다.
    • 위 POST 요청에선 요청이 전송되면 sessionStorage에 ‘is-authenticated’라는 키에 true 값을 넣어준다.
    • 이후 200번 상태코드를 넣어준다.
    • user 정보를 가져오는 GET 요청에선 조건에 따라 응답을 다르게 설정해주었다.
      • sessionStorage에 'is-authenticated' 키의 값을 가져온다.
      • 만일 값이 false라면 상태코드 403번 (Forbidden, 서버가 요청을 이해했지만 승인 거부함)과 에러메시지를 전송하고
      • 만일 값이 true라면 상태코드 200번과 username을 함께 리턴해준다

2. MSW 직접 적용하기 (브라우저에서)

2.1 MSW 라이브러리 설치

  • 이건 맨 처음 프로젝트 설정에서 했으니 넘어가겠음
  • yarn add msw --dev

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

브라우저에서 사용하기 위해선 MSW를 서비스 워커에 등록하는 과정이 필요하다. 아래 명령어를 입력하면 서비스 워커 등록을 위한 파일이 public 폴더에 추가된다

npx msw init <PUBLIC_DIR> --save

npx msw init public/ --save
  • public/ 폴더는 주로 프로젝트의 정적 리소스를 담는 폴더이다. CRA, Next.js, Vite에서 기본적으로 셋팅 되어있다.
  • 다른 프로젝트의 경우 public 디렉토리가 다를 수 있는데, 해당 링크에서 참고할 수 있다.

2.3 Worker 설정

  • scr/mocks 폴더 내에 brower.js 파일을 만든다.
  • 생성한 browers.js 안에서 worker 인스턴스를 생성하고, request handles를 인자로 넣어준다.
import { setupWorker } from "msw";
import { handlers } from "./handlers";

export const worker = setupWorker(...handlers);

2.4 Worker 실행

  • 우리가 mocking 한 코드를 어플리케이션에 적용하고 실행하려면 우리 어플리케이션에 import해와야한다.
  • 그러나 mocking은 개발시에만 사용되는 기술이기 때문에 mocking이 필요할 때만 해당 파일을 가져오면 된다.
  • 우리는 지금 mocking이 필요하기 때문에 worker을 실행하는 코드를 추가해주면 된다.
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

// 아래 if문이 worker을 실행하는 코드
if (process.env.NODE_ENV === 'development') {
    // 공식문서에선 아래 코드를 이용하라 하였다.
    const { worker } = require('./mocks/browser')
    // 그러나 Vite를 이용하여 개발하는 경우 require를 사용하지 않으므로 await import를 해주면 된다.
    const { worker } = await import("./mocks/browser");
  worker.start()
}

ReactDOM.render(<App />, document.getElementById('root'))


[MSW] Mocking enabled라는 문구가 콘솔창에 뜨면 mocking이 활성화 된 것이다 !

2. 실습해보기 with TodoList (추후 추가예정)

  • 로그인 기능이 있는 TodoList를 실습하여 추가할 예정이다.

+ Recent posts