
경고: 테스트 내에서 Formik을 업데이트했는데 act(…)로 감싸지 않았습니다
소개
React에서 테스트를 실행할 때, 테스트 내에서 Formik을 업데이트했는데 act(…)로 감싸지 않았다는 경고 메시지가 표시될 수 있습니다. 테스트는 여전히 작동할 수 있지만, 정확한 결과를 보장하고 브라우저에서 사용자의 경험을 모방하기 위해서는 이 경고를 처리하는 것이 중요합니다. 이 블로그 글에서는 이 경고의 가능한 원인을 탐구하고 해결 방법을 제공합니다.
경고 원인
이 경고 메시지는 테스트를 수행할 때 React 상태 업데이트를 발생시키는 코드가 act(…)로 감싸지지 않았다는 것을 제안합니다. 이렇게 하면 테스트하는 동작이 사용자가 브라우저에서 볼 것과 정확히 일치하는지 확인할 수 있습니다. 코드를 감싸지 않으면 예상치 못한 또는 신뢰할 수 없는 테스트 결과가 발생할 수 있습니다.
해결 방법
해결 방법 1: Mount할 때 validateOnMount 속성 검증
이 경고의 한 가지 가능한 원인은 Formik의 validateOnMount 속성과 관련이 있습니다. 이 문제는 Formik의 버그로 보고되었으며, 당신의 어서션(assertion)에서 waitFor 메서드를 사용하여 해결할 수 있습니다. 아래는 예시입니다:
await waitFor(() =>
expect(getByText('Component header')).toBeInTheDocument()
);
waitFor을 사용하여, 특정 컴포넌트가 렌더링되기 전에 테스트가 대기하도록 보장합니다.
해결 방법 2: jest.useFakeTimers() 사용
@testing-library/react-native을 사용하면서 이 경고가 발생하는 경우, jest.useFakeTimers()와 jest.runAllTimers()를 사용하는 것이 한 가지 해결 방법입니다. 다음은 예시입니다:
jest.useFakeTimers();
// 텍스트 변경하기
const textInput = getByA11yHint('Enter the text here');
act(() => {
fireEvent.changeText(textInput, 'test123');
});
// 타이머 실행하기
act(() => {
jest.runAllTimers();
});
// 업데이트된 값 어서션(assertion)하기
expect(textInput.props.value).toBe('test123');
jest.useFakeTimers()와 jest.runAllTimers()를 사용하여 타이머가 올바르게 실행되도록 보장합니다.
해결 방법 3: await를 screen.findByRole과 함께 사용하기
@testing-library/react을 사용하면서 이 경고가 발생하는 경우, await를 screen.findByRole과 함께 사용하는 대안적인 해결 방법이 있습니다. 이렇게 하면 어서션(assertion)을 진행하기 전에 promises가 해결되도록 보장할 수 있습니다. 다음은 예시입니다:
import { screen } from "@testing-library/react"
test('테스트 이름', async () => {
/* 여기에 다른 내용 ... */
// Before
expect(screen.getByRole(...)).toBeEnabled();
// After
expect(await screen.findByRole(...)).toBeEnabled();
});
await와 screen.findByRole을 함께 사용하여 promise가 해결될 때까지 기다려 정확한 어서션이 가능합니다.
결론
Formik을 업데이트할 때 act(…)로 감싸지 않았다는 경고는 적절한 테스트 방법을 필요로 함을 나타냅니다. mount 검증, 가짜 타이머 사용, findByRole과 await 사용 등을 통해 이 경고를 처리하여 정확한 테스트 결과와 사용자 경험을 더욱 잘 모방할 수 있습니다. 제공된 해결 방법을 따르면 이 경고를 제거하고 React 테스트의 신뢰성을 향상시킬 수 있습니다.