React Testing Library와 함께 간단한 TodoList 만들어보기
- javascript
인프런의 '따라하며 배우는 리액트 테스트'를 참고하였습니다. 페이지는 새롭게 설계하였습니다.
아주 간단한 TodoList를 만들고 테스트를 작성해 보자.
1. 프로젝트 생성
create-react-app으로 프로젝트를 생성한다. typescript를 사용해볼 것이다.
npx create-react-app todolist-with-test --template typescript
npx create-react-app todolist-with-test --template typescript
이제 필요한 라이브러리를 깔아 주자. testing library와 같은 경우 cra로 어플리케이션 생성시 기본적으로 깔려 있다. eslint만 깔아주자.
npm install eslint-plugin-testing-library eslint-plugin-jest-dom --save-dev
npm install eslint-plugin-testing-library eslint-plugin-jest-dom --save-dev
CRA로 앱을 만들 때 자동으로 설정된 eslint config가 package.json에 있다. 이를 삭제하자.
// 이 부분 삭제
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
// 이 부분 삭제
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
그리고 루트에 .eslintrc.json
파일을 만들고 다음과 같이 작성한다. react, jest, testing-library, jest-dom에 대한 eslint 설정을 해주는 것이다.
{
"plugins": ["testing-library", "jest-dom"],
"extends": [
"react-app",
"react-app/jest",
"plugin:testing-library/react",
"plugin:jest-dom/recommended"
]
}
{
"plugins": ["testing-library", "jest-dom"],
"extends": [
"react-app",
"react-app/jest",
"plugin:testing-library/react",
"plugin:jest-dom/recommended"
]
}
그리고 페이지가 약 3개가 될 것으로 예상되므로 react router를 설치한다.
npm install react-router-dom
npm install react-router-dom
이 정도로 하고 당장 todo list를 만들어보자.
2. TodoList 설계
설계는 단순하다. 로그인 페이지를 만들고 로그인을 하면 todo list 페이지로 넘어가는 것이다. 이때 로그인이 성공할 시 해당 유저에 대해 저장된 todolist 항목들이 불러와진다.
todo list 페이지는 todo를 추가하고 삭제할 수 있어야 한다.
우리는 로그인 페이지, todo list 페이지, 페이지를 찾지 못했을 때 이동하는 만들 것이다.
먼저 src/pages 폴더를 만들고 LoginPage, TodoListPage, NotFoundPage폴더, 그리고 각각에 속한 index.tsx를 만들어준다.
간단하게 각 페이지에는 각 페이지의 이름을 출력하는 컴포넌트를 만들어준다.
// src/pages/LoginPage/index.tsx
function LoginPage() {
return <div>로그인 페이지입니다.</div>;
}
export default LoginPage;
// src/pages/LoginPage/index.tsx
function LoginPage() {
return <div>로그인 페이지입니다.</div>;
}
export default LoginPage;
// src/pages/TodoListPage/index.tsx
function TodoListPage() {
return <div>to do list 페이지입니다.</div>;
}
export default TodoListPage;
// src/pages/TodoListPage/index.tsx
function TodoListPage() {
return <div>to do list 페이지입니다.</div>;
}
export default TodoListPage;
// src/pages/NotFoundPage/index.tsx
function NotFoundPage() {
return <div>페이지 이동을 실패했을 때 오는 페이지입니다.</div>;
}
export default NotFoundPage;
// src/pages/NotFoundPage/index.tsx
function NotFoundPage() {
return <div>페이지 이동을 실패했을 때 오는 페이지입니다.</div>;
}
export default NotFoundPage;
이제 각 페이지들을 라우터에 추가해 줄 것이다. App.tsx와 App.css 그리고 App.test.tsx는 지우고 index.tsx를 다음과 같이 수정한다. react-router는 어째 늘 문법이 조금씩 바뀌는 것 같다. 다시 공식 문서를 찾아서 그대로 했다.
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import LoginPage from "./pages/LoginPage";
import NotFoundPage from "./pages/NotFoundPage";
import TodoListPage from "./pages/TodoListPage";
const router = createBrowserRouter([
{ path: "/", element: <TodoListPage /> },
{ path: "/login", element: <LoginPage /> },
{ path: "*", element: <NotFoundPage /> },
]);
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import LoginPage from "./pages/LoginPage";
import NotFoundPage from "./pages/NotFoundPage";
import TodoListPage from "./pages/TodoListPage";
const router = createBrowserRouter([
{ path: "/", element: <TodoListPage /> },
{ path: "/login", element: <LoginPage /> },
{ path: "*", element: <NotFoundPage /> },
]);
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
3. TodoList 페이지
이제 볼품없게나마 todo list 페이지를 만들어보자.
1. Mock Service Worker
Mock Service Worker는 서버와의 통신을 모킹해주는 라이브러리다. 이를 사용하면 서버가 없어도 테스트를 할 수 있다.
이는 브라우저에 서비스 워커를 등록하여 서버에 요청을 보낼 때 외부로 나가는 요청을 가로채고, 가로챈 요청에 대한 응답을 Mock Service Worker의 클라이언트 사이드에서 만들어주는 방식으로 동작한다.
이 응답은 핸들러에서 처리하며 이렇게 만든 응답은 브라우저로 다시 보내진다.
이때 브라우저 대신 서버를 생성한 후 Node로 서버를 직접 만들어 줄 수도 있다.
참고
https://www.daleseo.com/mock-service-worker/