testing-library-react의 "update was not wraped in act()" 경고를 해결하려면 어떻게 해야 합니까?
나는 부작용을 일으키는 단순한 부품으로 일하고 있다.내 시험은 통과했지만 경고음이 울리고 있어Warning: An update to Hello inside a test was not wrapped in act(...).
.
저도 잘 모르겠어요waitForElement
이 시험을 치르는 가장 좋은 방법이에요.
내 컴포넌트
export default function Hello() {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
setPosts(response.data);
}
fetchData();
}, []);
return (
<div>
<ul>
{
posts.map(
post => <li key={post.id}>{post.title}</li>
)
}
</ul>
</div>
)
}
마이 컴포넌트 테스트
import React from 'react';
import {render, cleanup, act } from '@testing-library/react';
import mockAxios from 'axios';
import Hello from '.';
afterEach(cleanup);
it('renders hello correctly', async () => {
mockAxios.get.mockResolvedValue({
data: [
{ id: 1, title: 'post one' },
{ id: 2, title: 'post two' },
],
});
const { asFragment } = await waitForElement(() => render(<Hello />));
expect(asFragment()).toMatchSnapshot();
});
갱신된 답변:
아래의 @mikaelrs 코멘트를 참조해 주세요.
wait For 또는 wait For Element는 필요 없습니다.대기할 수 있는 약속을 반환하는 findBy* 셀렉터를 사용하면 됩니다.예: 검색 대기자TestId('list');
권장되지 않는 답변:
사용하다waitForElement
다음 문서에서 올바른 방법입니다.
조롱당할 때까지 기다려라
get
request promise가 해결되고 컴포넌트가 setState를 호출하여 재렌더합니다.waitForElement
콜백이 에러를 발생시키지 않을 때까지 대기합니다.
다음은 해당 사례의 작업 예를 제시하겠습니다.
index.jsx
:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function Hello() {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
setPosts(response.data);
};
fetchData();
}, []);
return (
<div>
<ul data-testid="list">
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
index.test.jsx
:
import React from 'react';
import { render, cleanup, waitForElement } from '@testing-library/react';
import axios from 'axios';
import Hello from '.';
jest.mock('axios');
afterEach(cleanup);
it('renders hello correctly', async () => {
axios.get.mockResolvedValue({
data: [
{ id: 1, title: 'post one' },
{ id: 2, title: 'post two' },
],
});
const { getByTestId, asFragment } = render(<Hello />);
const listNode = await waitForElement(() => getByTestId('list'));
expect(listNode.children).toHaveLength(2);
expect(asFragment()).toMatchSnapshot();
});
100% 적용 범위에서의 유닛 테스트 결과:
PASS stackoverflow/60115885/index.test.jsx
✓ renders hello correctly (49ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.jsx | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 4.98s
index.test.jsx.snapshot
:
// Jest Snapshot v1
exports[`renders hello correctly 1`] = `
<DocumentFragment>
<div>
<ul
data-testid="list"
>
<li>
post one
</li>
<li>
post two
</li>
</ul>
</div>
</DocumentFragment>
`;
소스 코드: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60115885
오류가 발생했습니다.
console.error
Warning: A suspended resource finished loading inside a test, but the event was not wrapped in act(...).
When testing, code that resolves suspended data should be wrapped into act(...):
act(() => {
/* finish loading suspended data */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
코드:
test('check login link', async () => {
renderRouter({ initialRoute: [home.path] });
const loginLink = screen.getByTestId(dataTestIds.loginLink);
expect(loginLink).toBeInTheDocument();
userEvent.click(loginLink);
const emailInput = screen.getByTestId(dataTestIds.emailInput);
expect(emailInput).toBeInTheDocument();
}
다음과 같이 해결했습니다.
test('check login link', async () => {
renderRouter({ initialRoute: [home.path] });
const loginLink = screen.getByTestId(dataTestIds.loginLink);
expect(loginLink).toBeInTheDocument();
userEvent.click(loginLink);
await waitFor(() => {
const emailInput = screen.getByTestId(dataTestIds.emailInput);
expect(emailInput).toBeInTheDocument();
});
}
방금 callback fn - wait For()로 랩했습니다.
아마 누군가에게는 도움이 될 것이다.
나에게 해결책은 '기다리는 것'이었다.waitForNextUpdate
it('useMyHook test', async() => {
const {
result,
waitForNextUpdate
} = renderHook(() =>
useMyHook(),
);
await waitForNextUpdate()
expect(result.current).toEqual([])
}
WaitFor
제겐 효과가 있었어요.findByTestId
여기에 언급되어 있지만, 같은 액션 에러가 발생하고 있습니다.
솔루션:
it('Should show an error message when pressing “Next” with no email', async () => {
const { getByTestId, getByText } = render(
<Layout buttonText={'Common:Actions.Next'} onValidation={() => validationMock}
/>
);
const validationMock: ValidationResults = {
email: {
state: ValidationState.ERROR,
message: 'Email field cannot be empty'
}
};
await waitFor(() => {
const nextButton = getByTestId('btn-next');
fireEvent.press(nextButton);
});
expect(getByText('Email field cannot be empty')).toBeDefined();
위의 slideshowp2의 답변은 좋으나 특정 예에 따라 다릅니다.(그의 대답은 공리적인 약속이 해결될 때까지 기다리지 않기 때문에 효과가 없는 것처럼 보인다; 항상 있다.list
testid
단, 쉽게 수정할 수 있습니다.)
예를 들어 코드 변경 후list
testId
발견, 어설트 실행, 그리고 또 다른 실행useEffect
트리거되어 사용자가 상관하지 않는 상태 갱신이 발생합니다. 동일한 정보를 얻을 수 있습니다.act
다시 문제 발생.일반적인 해결방법은 다음과 같습니다.render
에act
어설션과 테스트 종료 전에 모든 업데이트가 완료되었는지 확인합니다.또한, 그러한 주장들은 다음과 같이 할 필요가 없습니다.waitFor
아무거나.다음과 같이 테스트 본체를 다시 작성합니다.
axios.get.mockResolvedValue({
data: [
{ id: 1, title: 'post one' },
{ id: 2, title: 'post two' },
],
});
let getByTestId;
let asFragment;
await act(()=>{
const component = render(<Hello />);
getByTestId = component.getByTestId;
asFragment = component.asFragment;
});
const listNode = getByTestId('list');
expect(listNode.children).toHaveLength(2);
expect(asFragment()).toMatchSnapshot();
(가져오기act
테스트 라이브러리에서)를 참조해 주세요.
주의:render
에 싸여 있다act
목록 검색은 다음을 사용하여 수행합니다.getBy*
비동기식이 아닙니다!모든 약속의 해결은 그 전에 완료됩니다.getByTestId
테스트 종료 후 상태 갱신은 이루어지지 않습니다.
언급URL : https://stackoverflow.com/questions/60115885/how-to-solve-the-update-was-not-wrapped-in-act-warning-in-testing-library-re
'source' 카테고리의 다른 글
들어오는 장고 요청의 JSON 데이터는 어디 있나요? (0) | 2023.02.08 |
---|---|
UNION을 사용할 때 json[] 유형의 등호 연산자를 식별할 수 없습니다. (0) | 2023.02.08 |
Json 문자열을 C# 객체 목록으로 변환 (0) | 2023.02.08 |
골랑 구조의 XML 및 JSON 태그? (0) | 2023.02.08 |
Wordpress - 포스트 편집 페이지의 카테고리 목록 순서 (0) | 2023.02.08 |