-
jest + React testing library + msw 테스트 초기 설정프론트엔드 2023. 1. 11. 15:24728x90반응형SMALL
이번 프로젝트를 시작하면서 TDD를 도입해보고자 미리 연습을 해보고 싶어서 이번 포스팅을 작성하게 되었습니다.
프로젝트는 Create React App typescript에 패키지 매니저는 yarn berry를 사용하고 있습니다.
해당 프로젝트 설정은 밑의 링크를 확인해주세요!
CRA + typescript + yarn berry
오늘의 포스팅은 yarn berry 패키지 매니저를 이용한 프로젝트 설정 방법을 살펴보도록 하겠습니다. yarn berry를 사용한 이유는 npm, yarn classic의 단점을 보완하고 pnp 방식을 이용해 배포할 경우 패키
blog.beomseok.dev
목차
1. msw란?
2. 설치 방법
3. 초기 설정
4. 예제
1. msw란?
- Mocking Service Worker
- 서비스 워크를 사용하여 네트워크 호출을 가로채는 API 모킹 라이브러리이다.
- 프론트엔드의 요총에 가짜 데이터를 응답해준다.
- 모킹이 네트워크 단에서 일어나기 때문에 프론트앤드 코드를 실제 백엔드 API와 네트워크 통신하는 것과 크게 다르지 않게 작성할 수 있다.
- REST API와 GraphQL을 모두 지원한다.
2. 설치 방법
2.1 msw, 의존성 설치
yarn add -D msw //밑의 의존성은 설치되지 않았을 경우 설치해줘야 한다. yarn add -D jest @testing-library/react @testing-library/user-event
2.2 서비스 워크 코드 생성
npx msw init public/ --save
msw는 브라우저에서 서비스 워크를 통해서 작동하기 때문에 서비스 워커 등록을 위한 기본적인 코드가 필요하다.
MSW에서 제공하는 CLI 도구를 사용하면 이 코드를 쉽게 만들어낼 수 있다.
3. 초기 설정
3.1 요청 핸들러 작성
- 요청이 들어왔을 경우 임의의 응답을 해주는 핸들러 코드를 작성
- src/mocks라는 디렉토리를 두는 것이 일반적이다.
- Express.js 서버에서 보이는 코딩 패턴과 유사하게 핸들러를 구사할 수 있다.
// /src/mocks/handlers.js import {rest} from 'msw'; const todos = ['todo1', 'todo2', 'todo3']; export const handlers = [ rest.get('/todos', (req,res,ctx)=>{ return res(ctx.status(200), ctx.json(todos)); }), rest.post('/todos', async (req,res,ctx)=>{ const todo = await req.json(); todos.push(todo); return res(ctx.status(201)); }) ];
위와 같은 경우 아래 두 가지 path에 대한 api가 생성된 것이다.
- GET /todos handler
- POST /todos handler
3.2 서비스 워커 생성
//setUpTests.ts import {setupWorker} from 'msw'; import {handlers} from './handlers'; export const worker = setupWorker(...handlers);
setUpWorker() 함수를 사용해서 서비스 워커를 생성한다.
3.3 서비스 워커 삽입
// /src/index.js import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import App from "./App"; import { worker } from "./mocks/worker"; if (process.env.NODE_ENV === "development") { worker.start(); } const rootElement = document.getElementById("root"); const root = createRoot(rootElement); root.render( <StrictMode> <App /> </StrictMode> );
4. 예제
간단한 todolist를 구현해보고, todo 목록을 api를 통해 가져오고, 새로운 todo를 보내는 예제를 구현해보도록 하겠습니다.
4.1 UI 코드 작성
// TodoList.tsx import React, { ChangeEvent, useEffect, useState } from 'react'; import axios from 'axios'; function TodoList() { const [todoList, setTodoList] = useState([]); const [todo, setTodo] = useState(''); const handleChange = (e: ChangeEvent<HTMLInputElement>) => { setTodo(e.target.value); }; const handleClick = async () => { await axios.post('/todos', { todo }); getTodoList(); }; const getTodoList = async () => { const { data } = await axios.get('/todos'); setTodoList(data); }; useEffect(() => { getTodoList(); }, []); return ( <div> <ul> {todoList.map((todo) => ( <li>{todo}</li> ))} </ul> <input type='text' aria-label='todo-input' onChange={handleChange} value={todo} /> <button onClick={handleClick}>제출</button> </div> ); } export default TodoList;
4.2 테스트 서버 작성
// /src/mocks/server.js import { setupServer } from "msw/node"; import { handlers } from "./handler"; export const server = setupServer(...handlers);
4.3 테스트 서버 설정
// /src/setupTest.js import "@testing-library/jest-dom"; import {server} from './mocks/server'; beforeAll(()=>server.listen()); afterEach(()=>server.resetHandlers()); afterAll(()=>server.close());
4.4 테스트 코드 작성
import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import TodoList from './TodoList'; test('renders learn react link', async () => { render(<TodoList />); const todoList = await screen.findAllByRole('listitem'); expect(todoList).toHaveLength(3); const input = screen.getByRole('textbox'); const button = screen.getByRole('button'); await userEvent.type(input, 'todo4'); userEvent.click(button); expect(await screen.findByText('todo4')).toBeInTheDocument(); });
4.5 결과
테스트 결과 최종 결과
위와 같이 CRA 프로젝트에 jest, React Testing Library, msw를 통해 테스트 환경을 구축해보았습니다.
각 라이브러리나 코드에 대한 설명이 대체로 부족한 것 같아서 다음 포스팅에서는 좀 더 세부적으로 알아보도록 하겠습니다.
반응형LIST'프론트엔드' 카테고리의 다른 글
Storybook 컴포넌트 만들기 2 (0) 2023.04.18 Storybook 컴포넌트 만들기 1 (0) 2023.04.17 Storybook CRA에 적용하기 (0) 2023.04.17 TDD를 해보자 (0) 2023.02.07 CRA + typescript + yarn berry (0) 2023.01.11