[Vue] MSW (Mock Service Worker) 연동

  • backend api가 준비 되지 않은 상태에서 http(get/post/put/delete 등) 메소드 호출에 대해서 사용자가 미리 정의한 응답 값을 전달한다.
  • 실제 api를 호출하는 것과 같은 상황을 만들수 있다.
  • 네트워크 레벨에서 요청에 대한 응답을 가로채서 설정된 값으로 반환한다.
  • Service Worker를 사용( Web Workers 와 다르다.)
  • 초기 설정외 production 용으로 배포하기위해 별도 코드 수정 필요 없음

작업 순서

  1. 설치
  2. 기본 설정
  3. Mock Handler 정의
  4. 설정 확인
  5. 기타

1. 설치

npm i -D msw

2. 기본 설정

  1. src/mocks 폴더 생성

    • http 요청에 대한 응답 핸들러 정의 폴더
  2. Mock Service Worker 생성

# ./public/mockServiceWorker.js 생성된다.
npx msw init public --save
  1. src/mocks/browser.ts
    • http 요청에 대한 응답 설정 파일
import { setupWorker } from 'msw'
import todoAPIHandler from './todo/todoAPIHandler';
export const worker = setupWorker(
    // mock handler 등록
);
  1. vue - browser 설정
// main.ts
import { createApp } from "vue";
import App from "./App.vue";

// worker 실행 후 vue app초기화 실행
const prepare = async () => {
  if (process.env.NODE_ENV === "development") {
    const { worker } = await import("./mocks/browser");
    worker.start();
  }
  return Promise.resolve();
};

prepare().then(() => {
  createApp(App).mount("#app");
});

3. Mock Handler 정의

  1. handler 정의
  • API 요청 URL 에 대한 응답 값을 정의한다.
  • 간단한 응답은 바로 정의하지만 길어질 경우 json 파일 또는 별도 메소드로 분리
// src/mocks/todo/todoAPIHandler.ts
import { rest } from "msw";
import selectTodosOKJson from "./datas/selectTodosOKJson.json";
import { selectTodosOK } from "./datas/selectTodo";

export default [
  // get 요청에 대한 응답 - json
  rest.get("https://jsonplaceholder.typicode.com/todos", (req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json([
        {
          userId: 1,
          id: 1,
          title: "delectus aut autem",
          completed: false,
        },
      ])
    );
  }),

  // get 요청에 대한 응답 - json 파일
  rest.get("https://jsonplaceholder.typicode.com/todos", (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(selectTodosOKJson));
  }),

  // get 요청에 대한 응답 - 메소드 호출
  rest.get("https://jsonplaceholder.typicode.com/todos", (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(selectTodosOK()));
  }),
];
  1. mock handler 등록
  • browser.ts 파일에 mock handler를 등록
  • handler는 요청 api 종류 별로 분리하자
import { setupWorker } from 'msw'
import todoAPIHandler from './todo/todoAPIHandler';
import postAPIHandler from './post/postAPIHandler';
export const worker = setupWorker(
    // mock handler 등록
    ...todoAPIHandler,

    ...postAPIHandler

);

4. 설정 확인

  1. msw 설정이 되면 크롬 개발자 툴 콘솔에 아래와 같은 메세지 출력된다.
[MSW] Mocking enabled.
  1. mock handler에 등록 되지 않은 api를 요청하는 경우 콘솔에 아래와 같은 메세지 출력
    devUtils.ts:17 [MSW] Warning: captured a request without a matching request handler:
    • GET https://jsonplaceholder.typicode.com/todos
    Did you mean to request "GET https://jsonplaceholder.typicode.com/posts" instead?
    If you still wish to intercept this unhandled request, please create a request handler for it.
    Read more: https://mswjs.io/docs/getting-started/mocks

위와 같은 메세지 출력을 원하지 않는 경우 아래와 같이 onUnhandledRequest 설정 추가

    worker.start({
      onUnhandledRequest: 'bypass',
    });

5. 기타

  1. Get 요청 값 얻기
  rest.get(
    "https://jsonplaceholder.typicode.com/todos/:id",
    (req, res, ctx) => {
      const { id } = req.params; // 12
      const testId = req.url.searchParams.get("test_id"); // 123

      if (id == "ok") {
        // return res(ctx.status(200), ctx.json(selectTodoByIdOK(123)));
        return res(ctx.json(selectTodoByIdOK(123)));
      } else {
        return res(ctx.status(400), ctx.json({ message: `Unknown error` }));
      }
    }
  ),
  1. body 값 얻기
  // post 요청 부분
  const param = {
      userId: 1,
      title: "mock data",
      completed: false,
    };
  axios.post('https://jsonplaceholder.typicode.com/todos', param)
  .then( (req) => {
    console.log(req.data);
  });

  // handler 응답 부분
  rest.post("https://jsonplaceholder.typicode.com/todos", async (req, res, ctx) => {
    // req.body > 'body' is deprecated
    const param = await req.json();
    console.log(param);
    return res(ctx.status(200));
  }),

'JS' 카테고리의 다른 글

babel-webpack 설정  (0) 2020.07.17
babel setting  (0) 2020.07.14
Sinon.JS  (0) 2019.08.26
Mocha-Sinon 개발 환경  (0) 2019.08.20
[Vuejs] mocha+chai+sinon 테스트  (0) 2019.08.13

+ Recent posts