act()에 대해 알아야 할 모든 것act() 함수에 익숙해질 것입니다. React 앱을 테스트하는 데 있어 기본적인 개념임에도 불구하고, 종종 가장 혼란스럽고 오해받는 부분 중 하나입니다.act()가 필요한지 설명하기 어려웠습니다. (하지만 이 페이지에서 명확히 해드리겠습니다!)act()로 감싸야 합니다. 이렇게 하면 React가 모든 상태 변경과 부수 효과를 완전히 처리한 후에 나머지 테스트(즉, 어설션)가 계속 진행되도록 보장할 수 있습니다.act()에 대해 생각할 필요가 없습니다. 이 함수들은 이미 act()로 기능을 감싸고 있기 때문입니다:userEvent를 사용한 사용자 상호작용 (예: await userEvent.click(...))await findBy... 함수들 (예: await screen.findByText("..."))waitFor(...) 함수act()로 감싸지지 않은 업데이트가 발생했다는 유명한 오류가 나타날 수 있습니다.act()로 감싸지지 않았다는 경고입니다. 이는 테스트에서 '오래된' 상태에 대해 어설션을 하고 있을 수 있으며, 실제 버그를 인식하거나 잡지 못할 수 있음을 의미합니다.act()를 올바르게 사용했다면 쉽게 잡을 수 있었던 큰 버그를 도입한 적이 있습니다!)act()에 대해 알아야 할 모든 것입니다. 하지만 이 블로그를 읽고 있다면, 그것에 대해 모든 것을 정말로 이해하고 싶을 것입니다. 테스트를 작성하는 데 매우 중요한 부분이므로 완전히 이해하는 것이 합리적입니다.act가 포함되어 있습니다. import React, from 'react'로 가져올 수 있습니다.@testing-library/react에서 가져오세요:@testing-library/react에서 가져온 버전은 추가 기능이 거의 없는 매우 가벼운 래퍼입니다. 실제 react의 act() 구현을 감싸지만, 다음과 같은 변경 사항이 있습니다:IS_REACT_ACT_ENVIRONMENT가 true로 설정되지 않은 경우, 테스트 환경 외부에서 act()를 호출하려고 하면 React가 경고합니다.@testing-library의 act() 래퍼를 사용하면 올바르게 설정됩니다.act()가 GitHub에서 어떻게 구현되어 있는지 확인할 수 있습니다. (그리고 레거시 이유로 세 번째 버전의 act()가 있다는 것을 알 수 있습니다.)react 패키지에서 act()를 사용하는 것으로 충분할 수 있지만, 일관성과 매우 드문 엣지 케이스를 위해 항상 RTL에서 가져오는 것이 좋습니다!act()를 사용하지 않으면 테스트에서 현재 렌더링된 상태가 오래된 상태가 되는 경우를 보여드리겠습니다.count를 1씩 증가시킵니다:Count: 0을 표시하고 있기 때문입니다:vi.advanceTimersByTime(10)을 act(...)로 감싸면 이제 통과합니다:await screen.findByText('Count: 1')를 사용할 수도 있습니다!await findBy... 함수는 내부적으로 act()를 사용하기 때문입니다.click 기능을 호출하는 예제입니다 (userEvent를 통해서가 아님).act()를 사용해야 하는 가장 일반적인 방법 중 하나라고 생각합니다.renderHook()을 사용하여 훅을 격리하여 테스트할 때, 상태를 업데이트하는 함수를 호출할 수 있습니다. 이러한 경우에는 act()로 감싸야 합니다.act()를 사용하는 예제:result.current.value의 값이 0으로 유지되기 때문에 실패합니다:act()를 사용하면 이제 올바른 상태 값을 갖게 됩니다:someButtonElement.click()을 직접 호출하는 경우userEvent를 통해서가 아님)fireEvent를 통해 클릭 등) - 특히 비동기 기능을 트리거할 때setTimeout, setIntervalact()를 과도하게 사용하기보다는 렌더링/상태 변경을 기다리도록 (waitFor 또는 findBy...) 시도해야 합니다.fireEvent 호출 (예: fireEvent.click(...))을 act()로 감쌀 필요가 없습니다.fireEvent가 비동기 함수를 트리거하고 그 자체로 await를 포함하는 경우에는 감싸야 할 때가 있습니다.fireEvent에 대해 act()를 건너뛰는 경향이 있습니다. (참고: 가능하다면 클릭과 같은 것을 트리거하기 위해 userEvent 기능을 사용하는 것이 더 좋습니다.)act()를 피하고 await screen.findBy...를 사용할 수 있습니다).await screen.findByText("Status: done")를 사용하여 act()를 피할 수도 있습니다)act() 호출 내에서 비동기 함수를 호출하지 않는 경우에는 거의 모든 경우에 비동기/대기 없이 수행할 수 있습니다. 그러나 React 업데이트 방식으로 인해 항상 작동하지 않는 엣지 케이스가 있습니다.await act(async () => {...})를 기본으로 사용해야 합니다.비동기 actFn: 테스트 중인 컴포넌트의 렌더링 또는 상호작용을 감싸는 비동기 함수입니다. actFn 내에서 트리거된 모든 업데이트는 내부 act 큐에 추가되며, 그런 다음 DOM에 대한 변경 사항을 처리하고 적용하기 위해 함께 플러시됩니다. 비동기이기 때문에 React는 비동기 경계를 넘는 모든 코드를 실행하고 예약된 업데이트를 플러시합니다.
act() 내부의 코드에 프로미스, 비동기/대기 또는 타이머가 포함된 경우act(() => {...})로도 작동합니다. 하지만 항상 비동기/대기를 사용하는 것이 더 쉽습니다)act() 사용은 최후의 수단이어야 합니다. 대부분의 코드에서는 필요하지 않습니다.act()로 감싸지 마세요userEvent.click() 등을 act()로 감싸지 않아야 합니다.await waitFor() 또는 await findBy...로 대체할 수 있다면 act()를 피하세요act() 호출을 피할 수 있는 경우가 매우 흔합니다. waitFor 또는 findBy... 함수 중 하나를 사용하여 어설션이 통과할 때까지 비동기 코드를 실행합니다.await findByText())은 React에서 상태 변경이 act()로 감싸지지 않았다는 경고 없이 거의 확실히 작동할 것입니다:act()를 waitFor로 대체할 수 있는 또 다른 예제입니다:act()를 피할 수 없습니다. 많은 핵심 기능에서 사용되기 때문입니다. 하지만 과도하게 사용하면 (예: 불필요한 act()로 모든 것을 감싸는 경우) 테스트 실행 시간이 영향을 받을 수 있습니다.@testing-library/react에서 가져온 act()를 사용하고, react 패키지에서 가져온 것을 사용하지 마세요.await act(async () => ...)act()로 감싸지 마세요. 가능한 한 적게 사용하고, 매우 작은 청크 (이상적으로는 한 줄/함수 호출만)를 감싸세요.act에 대한 경고가 나타나거나 테스트에서 상태 변경이 반영되지 않는 경우, 문제를 디버그하기 위해 일반적으로 수행하는 단계는 다음과 같습니다:.only를 추가하여 act() 경고가 있는 테스트를 찾습니다: test.only('my test', ...)return 문을 추가합니다.render() 바로 뒤에 return을 추가하세요.act()로 감싸세요act()로 감싸세요:.findBy...() (또는 waitFor()) 함수를 사용하여 어설션이 통과할 때까지 기다리세요. 이는 내부적으로 act()를 사용하므로 경고가 사라질 것입니다.await가 누락되었습니까? 모든 act() 호출 앞에 await를 추가하세요.act() 내부에 act()를 래핑하지 않았는지 확인하세요.beforeEach/afterEach 훅이 모든 것을 지우는지 확인하세요.act()가 실행되도록 await act(() => {})를 추가하세요.act()를 호출할 때 global.IS_REACT_ACT_ENVIRONMENT가 true와 같은지 확인하기 때문에 발생합니다.아직 댓글이 없습니다.
첫 번째 댓글을 작성해보세요!