가수면

테스트 종료와 비동기 업데이트 충돌 오류 본문

React/테스팅 라이브러리

테스트 종료와 비동기 업데이트 충돌 오류

니비앙 2023. 6. 27. 10:49
Warning: An update to Options inside a test was not wrapped in act ....
Warning: Can't perform a React state update on an unmounted component.

위 두 가지 오류의 대부분의 경우는 테스트가 끝난 뒤에 컴포넌트가 바뀌기 때문에 발생하는 오류이다.

 

예를 들어 초기 화면에 0이 잘 렌더링 되는지를 테스트하는 함수를 작성했다고 해보자.

테스트 함수는 잘 작성되었고 성공적으로 통과되어 언마운트까지 한 상황이다.

그러나 만약 해당 컴포넌트 안에 fetch 등의 비동기 로직이 있는 경우 문제가 발생할 수 있다.

테스트가 종료되어 이미 언마운트가 일어났음에도 불구하고 비동기 작업이 반환되어 컴포넌트를 렌더링 시키려는 상황이 발생하게 되는 것이다.

 

그리고 바로 이 경우가 위 두 종류의 오류를 발생시키는 경우다.

해결법

먼저 useEffect의 클린 업을 이용해 언마운트 시 요청을 취소하는 로직을 작성한다.

이때 AbortController API를 이용할 수 있다. AbortController 인터페이스는 하나 이상의 웹 요청을 취소할 수 있게 해준다.

  useEffect(() => {
    const controller = new AbortController();	// 생성자 작성
    axios  // fetch(url, { signal: controller.signal })...
      .get("url", { signal: controller.signal })	// 요청의 옵션으로 signal을 적는다.
      .then((response) => ...
      
    return () => {
      controller.abort();	// 요청 취소
    };
  }, []);

원래대로라면 이것만으로도 문제가 해결되어야 하지만, 해결되지 않을 수 있다.

 

이 경우 테스트 코드에서 명시적으로 언마운트해줘야 한다.

render의 unmount를 구조 분해한 뒤 문제가 되는 함수의 마지막에 unmount 호출해준다.

  test("스쿱을 먼저 추가했을 때 제대로 업데이트 되는지 테스트", async () => {
    const user = userEvent.setup();

    const { unmount } = render(<OrderEntry />);
    const grandTotal = screen.getByRole("heading", { name: /Grand total: \$/ });
    expect(grandTotal).toHaveTextContent("0.00");

    unmount();

 

'React > 테스팅 라이브러리' 카테고리의 다른 글

Playwright 기본  (0) 2024.04.24
msw  (0) 2023.06.30
테스팅 라이브러리 심화  (0) 2023.06.26
user-event  (0) 2023.06.23
테스팅 쿼리  (0) 2023.06.22
Comments