msw (Mock Service Worker)

Bin2·2022년 8월 2일
0
post-custom-banner

Mock Service Worker

Service Worker API를 사용하여 실제 요청을 가로채는 API 모킹 라이브러리 이다.

FrontEnd 개발 단계에서 백엔드 API가 준비되지 않더라도 실제 API 요청을 구현할 수 있고 테스트를 할 경우에도 유용하게 사용할 수 있다.

Install

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

Define Mocks

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

export const handlers = [
  rest.get("http://localhost:3030/scoops", (req, res, ctx) => {
    return res(
      ctx.json([
        { name: "Chocolate", imagePath: "/images/chocolate.png" },
        { name: "Vanilla", imagePath: "/images/vanilla.png" },
      ])
    );
  }),
  rest.get("http://localhost:3030/toppings", (req, res, ctx) => {
    return res(
      ctx.json([
        { name: "Cherries", imagePath: "/images/cherries.png" },
        { name: "M&Ms", imagePath: "/images/m-and-ms.png" },
        { name: "Hot fudge", imagePath: "/images/hot-fudge.png" },
      ])
    );
  }),
  rest.post("http://localhost:3030/order", (req, res, ctx) => {
    return res(ctx.json({ orderNumber: 123455676 }));
    // return res(ctx.status(500));
  }),
];

지정된 endpoint로 요청시 리턴 값을 지정할 수 있다.

Browser

브라우저 환경에서의 요청을 모킹한다.

// src/mocks/browser.js
import { setupWorker } from 'msw'
import { handlers } from './handlers'
// This configures a Service Worker with the given request handlers.
export const worker = setupWorker(...handlers)
// index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";

if (process.env.NODE_ENV === 'development') {
  const { worker } = require('./mocks/browser')
  worker.start()
}

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Node

노드 환경에서의 요청을 모킹한다.

// src/mocks/server.js
import { setupServer } from "msw/node";
import { handlers } from "./handlers";

export const server = setupServer(...handlers);

Test

만약 테스트시 Response 값을 변경하고 싶다면 ?

// src/setUptest.js
import "@testing-library/jest-dom";

import { server } from "./mocks/server";

beforeAll(() => server.listen());


afterEach(() => server.resetHandlers());

afterAll(() => server.close());
test("handles error for scoops and toppings routes", async () => {
  server.resetHandlers(
    rest.get("http://localhost:3030/scoops", (req, res, ctx) =>
      res(ctx.status(500))
    ),
    rest.get("http://localhost:3030/toppings", (req, res, ctx) =>
      res(ctx.status(500))
    )
  );

  render(<OrderEntry setOrderPhase={jest.fn()} />);
  await waitFor(async () => {
    const alerts = await screen.findAllByRole("alert");
    expect(alerts).toHaveLength(2);
  });
});
profile
Developer
post-custom-banner

0개의 댓글