Skip to content

Latest commit

 

History

History
225 lines (149 loc) · 5.85 KB

220715.md

File metadata and controls

225 lines (149 loc) · 5.85 KB

Mocking

외부 서비스에 의존하지 않고 독립적으로 실행이 가능한 단위 테스트를 작성하기 위해서 사용되는 테스팅 기법

프론트엔드에서 백엔드의 API를 활용해야 하는 것처럼, 백엔드 개발에 종속적이 부분이 있다면 해당 부분이 완성되기 전까지는 프론트엔드의 개발을 진행할 수 없다. -> Mocking을 이용!

기존에는 화면에 필요한 데이터의 상태를 애플리케이션의 내부 로직에 직접 Mocking 해서 필요한 화면에 붙이거나 Mock 서버를 별도로 만들었다.

그러나, 내부 로직에 직접 붙이는 경우에는, 구현이 쉽지만, 서비스 로직을 수정해야하고, HTTP 메소드와 네트워크의 응답 상태에 따라 각각 대응하기가 쉽지 않음.

Mock서버를 별도로 만드는 경우에는 서비스 로직을 수정하지 않아도 되지만, 데이터 상태 구현에 비용이나 인력이 더 많이 들게 된다.

또한 API 응답 상태에 따라 대기, 로딩, 에러 등의 여러가지 구현이 존재하는데, 이런 경우 각 케이스별로 임의의 상태를 만들어 보면서 개발하기 쉽지 않다!

MSW.js (Mock Service Worker)

msw공식문서

실제 API를 사용하는 것처럼 네트워크 수준에서 Mocking 가능하도록 해주는 라이브러리

Service Worker를 통해 HTTP요청을 가로챌 수 있기 때문에, 네트워크 요청을 보냈을 때 모의 응답을 보내줄 수 있다! 따라서 Mock서버를 구축하지 않아도 API를 네트워크 수준에서 Mocking할 수 있다.

img

설치 및 설정

Create-React-App 기반으로 REST API 모킹해보기

msw 설치

npm install msw --save-dev
# or
yarn add msw --dev

mocks 폴더 생성

mkdir src/mocks

handlers.js 파일 생성

touch src/mocks/handlers.js

인터셉트한 request에 따라 돌려 줄 mocked응답을 작성해두는 파일이다.

ex)

// src/mocks/handlers.js
import { rest } from 'msw'

export const handlers = [
  // Handles a POST /login request
  rest.post('/login', null),

  // Handles a GET /user request
  rest.get('/user', null),
]

msw 초기화

npx msw init <PUBLIC_DIR> --save

<PUBLIC_DIR> 은 프로젝트 starter를 무엇으로 했는지에 따라 확인하고 지정해주면 된다.

CRA인 경우엔 public/


browser.js 파일 생성

touch src/mocks/browser.js

msw에서 제공하는 서비스워커를 가져와서 위에서 작성한 handlers를 인자로 넘겨준다.

// src/mocks/browser.js
import { setupWorker } from 'msw'
import { handlers } from './handlers' // export default로 해줬을 경우 {} 제거

// This configures a Service Worker with the given request handlers.
export const worker = setupWorker(...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'))

개발 환경일 때, browser.js에서 worker를 가져와서 실행하는 코드를 추가한다.

API에 대해서 모의 응답이 아닌 실제 응답을 원할 때는 이 코드만 지우고 실행하면 된다.


작동 확인

컴포넌트에서 fetch(‘/login’) 진행 후 react 서버를 열고 콘솔을 확인했을 때

Mocking enabled 이라고 빨간 글씨가 적혀있다면 정상 작동하고 있는 것.

실습

Parameter name Description
request Information about the captured request.
response Function to create the mocked response.
context Context utilities specific to the current request handler.
// src/mocks/handlers.js
import { rest } from 'msw'

const handlers = [
    rest.get('/users', (req, res, ctx) => {
      return res(
        ctx.status(200),
        ctx.delay(1000),
        ctx.json([
            {
              id: 1,
              name: 'deer',
              age: 20
            },
            {
              id: 2,
              name: "coco",
              age: 20
            },
            {
              id: 3,
              name: "ddiyong",
              age: 20
            }
          ]
        )
      )
    }),
  ]

export default handlers
// src/MockingTest.js
import { useState } from 'react'

function MockingTest () {

  const [userData, setUserData] = useState();

  function getUsersHandler() {
    fetch('/users')
    .then((res) => {
      return res.json()
    })
    .then((json) => {
      setUserData(json)
    })
  }

  return (
    <div>
      <button onClick={getUsersHandler}>멤버</button>
      {userData &&
        userData.map((user) => (
          <div key={user.id}>이름 : {user.name} 나이 : {user.age}</div>
        ))
      }
    </div>
  );
}

export default MockingTest;

결과 화면

이미지


참고 링크들