RTL,Jest - 실사용연습(2)

hoin_lee·2023년 8월 10일
0

TIL

목록 보기
210/236

어제 작성한 코드가 엉망진창이었다는걸 오늘 코드를 작성하고 테스트를 진행하며 알 수 있었다
먼저 Home 페이지 컴포넌트를 만들었는데

import { useNavigate } from "react-router";
import Button from "../components/ui/Button";
import styles from "../styles/home.module.css";

const Home = () => {
  const navigation = useNavigate();
  const signinBtnRedirectHandle = () => navigation("signin");
  const signupBtnRedirectHandle = () => navigation("signup");
  return (
    <div className={styles.homeContainer}>
      <section className={styles.titleContainer}>
        <h1>TODOLIST에 오신 걸 환영합니다!</h1>
      </section>
      <section className={styles.redirectBtnContainer}>
        <Button clickHandle={signinBtnRedirectHandle}>로그인</Button>
        <Button clickHandle={signupBtnRedirectHandle}>회원가입</Button>
      </section>
    </div>
  );
};

export default Home;

h1을 통해 간단한 title 글이 있고 로그인과 회원가입 페이지로 이동하는 버튼이 있다
원래는 아래와 같이 테스트 코드를 작성햇는데

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import Home from "../pages/Home";

describe("<Home />", () => {
  // 각 테스트가 시작 전 렌더링 하기
  beforeEach(() => {
    render(
      <MemoryRouter>
        <Home />
      </MemoryRouter>
    );
  });
  //홈페이지 타이틀 메세지가 잘 뜨는지 확인
  test("render home title massage", () => {
    const HomeTitleMessage = screen.getByRole("h1", {
      name: "TODOLIST에 오신 걸 환영합니다!",
    });
    expect(HomeTitleMessage).toBeInTheDocument();
  });

  //Login 버튼 누를시 signin페이지 이동
  test("click login button redirect /signin", () => {
    const loginButton = screen.getByRole("button", { name: "로그인" });
    fireEvent.click(loginButton);
    expect(window.location.pathname).toBe("/signin");
  });

  //signup버튼 누를시 signup페이지 이동
  test("click signup button redirect /signup", () => {
    const signupButton = screen.getByRole("button", { name: "회원가입" });
    fireEvent.click(signupButton);
    expect(window.location.pathname).toBe("/signup");
  });
});

그냥 뭐같이 다 빨간불 들어왔다. 모든 테스트가 실패했는데 차근차근 이유를 하나씩 찾아보자
먼저 공식문서와 구글링을 통해 해결했는데
첫번째 테스트에선 .toBeInTheDocument()가 에러가 생겼는데 해당 함수를 찾을 수 없다는 에러가 났다
리액트 테스팅 라이브러리가 아닌 jest dom을 사용해야 하는 것인데 import하지 않아서 생긴 에러였다. 가장 최상위에

import "@testing-library/jest-dom";

를 추가해주면 첫번째 테스트는 통과되는 걸 확인할 수 있다

그리고 2번째 3번째 테스트는 같은 에러가 일어났는데 expect(window.location.pathname).toBe("/signup") 해당 부분 자체가 제대로 동작하지 않는 에러가 있었다. expect상 url은 /로 나오는데 /signup으로나온다는 에러였다
뭐가 문제일까 검색하다 공식 문서를 확인하니 사용하는 방법이 조금 달랐다

먼저 맨처음 라우팅 하는 페이지 컴포넌트도 조금 다르게 사용하고 있었다. v6부터 변경되었다는데

//before
beforeEach(() => {
    render(
      <MemoryRouter>
        <Home />
      </MemoryRouter>
    );
  });
//after
beforeEach(() => {
    render(<Home />, { wrapper: BrowserRouter });
  });

공식문서를 따라 하니 정상적으로 렌더링 됐다

이후 test 코드쪽도 변경되었는데

 //회원가입버튼 누를시 signup페이지 이동
  test("click signup button redirect /signup", async () => {
    const signupButton = screen.getByRole("button", { name: "회원가입" });
    await fireEvent.click(signupButton);
    expect(window.location.pathname).toBe("/signup");
  });

Home컴포넌트에서 버튼을 찾은 후 진행한다
다만 달라진 점으론 async await 요소를 추가해서 fireEvent.click을 통해 로그인 버튼이 눌렸을 때 리다이렉트나 동작이 끝날때까지 기다리도록 한다
이후 expect(window.location.pathname).toBe("/signup")를 통해 회원가입 페이지의 주소로 이동했는지 확인한다

다만 화면 렌더링까지 완성된 것은 테스트 하지 못했다
정보를 찾기도 어렵거니와 사용자의 상호작용을 테스트 한다는 얘기도 있고.. 좀 더 검색해서 알아보면 나중에 한번 테스트 해봐야겠다

profile
https://mo-i-programmers.tistory.com/

0개의 댓글