ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React Testing Library] msw를 활용한 mock API 테스트
    React/jest 2023. 8. 4. 21:07

    3. MSW를 활용한 mock API 테스트

    본 라이브러리를 학습하기 위해 코딩앙마님의 강의를 수강하였습니다.

     

    3.1 Mock Serveice Worker 다운 및 세팅

     

    Node - Getting Started

    Mock Service Worker Docs

    mswjs.io

     

    Install - Getting Started

    Mock Service Worker Docs

    mswjs.io

    위 사이트를 방문해서 install 및 integrate를 해준다.

    src/mock 안에 handlers.js + server.js를 생성하면 된다.

     

    그 후 src/setupTests(생성X).js의 내용을 다음과 같이 수정한다.

    // jest-dom adds custom jest matchers for asserting on DOM nodes.
    // allows you to do things like:
    // expect(element).toHaveTextContent(/react/i)
    import '@testing-library/jest-dom';

    // src/setupTests.js
    import { server } from './mock/server.js';
    // Establish API mocking before all tests.
    beforeAll(() => server.listen());

    // Reset any request handlers that we may add during the tests,
    // so they don't affect other tests.
    afterEach(() => server.resetHandlers());

    // Clean up after the tests are finished.
    afterAll(() => server.close());

     

    3.2 api 이용해서 테스트

    실전이 아닌 연습용으로 무료 api를 사용했다.

    https://jsonplaceholder.typicode.com/

     

    JSONPlaceholder - Free Fake REST API

    {JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. Serving ~2 billion requests each month.

    jsonplaceholder.typicode.com

     

    src/mock/handlers.js를 다음과 같이 수정한다.

     

    import { rest } from 'msw';

    export const handlers = [
      // Match a GET request to a third-party server.
      rest.get('https://jsonplaceholder.typicode.com/todos', (req, res, ctx) => {
        return res(
          ctx.status(200), //500 : 서버 에러
          ctx.json([
            {
              id: 1,
              title: '청소',
              completed: true,
            },
            {
              id: 2,
              title: '설거지',
              completed: false,
            },
            {
              id: 3,
              title: '빨래',
              completed: true,
            },
          ])
        );
      }),
    ];

     

    src/component/TodoList.js를 다음과 같이 작성한다.

    import { useEffect, useState } from 'react';

    export default function TodoList() {
      const [todoList, setTodoList] = useState([]);
      const [errorMsg, setErrorMsg] = useState('');

      useEffect(() => {
          .then((response) => response.json())
          .then((json) => setTodoList(json))
          .catch(() => {
            setErrorMsg('에러 발생... ');
          });
      }, []);

      return (
        <>
          <h1>TodoList</h1>

          {errorMsg ? (
            <h5>{errorMsg}</h5>
          ) : (
            <ul>
              {todoList.map((todo) => (
                <li
                  key={todo.id}
                  style={{
                    textDecoration: todo.completed ? 'line-through' : undefined,
                  }}
                >
                  {todo.title}
                </li>
              ))}
            </ul>
          )}
        </>
      );
    }

     

    src/component/TodoList.test.js를 다음과 같이 작성한다.

     

    import { render, screen } from '@testing-library/react';
    import TodoList from './TodoList';
    import { rest } from 'msw';
    import { server } from '../mock/server';

    describe('TodoList', () => {
      test('TodoList 라는 제목이 있다.', () => {
        render(<TodoList />);
        const titleElement = screen.getByRole('heading', {
          name: 'TodoList',
        });
        // const titleElement = screen.getByText("TodoList")
        expect(titleElement).toBeInTheDocument();
      });
     
      test('리스트 3개가 잘 나온다.', async () => {
        render(<TodoList />);
        const listElement = await screen.findAllByRole('listitem');
        expect(listElement).toHaveLength(3);
      });
    });

    프로미스로 반환되므로, await screen.findAllByRole('listitem') 을 사용해야한다. 

     

     

    3.3 mock 서버 이용하여 에러 생성

    방법 1. 모든 api 서버 오류 처리

    src/mock/handlers.js를 다음과 같이 수정한다.

    import { rest } from 'msw';

    export const handlers = [
      // Match a GET request to a third-party server.
      rest.get('https://jsonplaceholder.typicode.com/todos', (req, res, ctx) => {
        return res(
          ctx.status(500),
     
        );
      }),
    ];

    하지만 , 이렇게 수정하면 모든 코드가 에러 처리되므로 테스트하기에 적절하지 않을 수 있다. 

     

    방법 2. test 안에서 서버 오류 처리

    import { render, screen } from '@testing-library/react';
    import TodoList from './TodoList';
    import { rest } from 'msw';
    import { server } from '../mock/server';
     
    test('에러가 났을 때 에러 메세지를 보여준다.', async () => {
        server.use(
          rest.get(
            (req, res, ctx) => {
              return res(
                ctx.status(500) //500 : 서버 에러
     
              );
            }
          )
        );

        render(<TodoList />);
        const errorElement = await screen.findByText('에러 발생...');
        expect(errorElement).toBeInTheDocument();
      });

    각 test 내부에서만 server 오류를 일으켜 각각 테스트에 적합하다.

    src/setupTests.js의 afterEach(() => server.resetHandlers()); 때문이다.

    'React > jest' 카테고리의 다른 글

    [React Testing Library] 기본 활용법, 유저 이벤트 테스트  (0) 2023.08.04
    [Jest] 기본 활용법  (0) 2023.08.03
Designed by Tistory.