gpt4 book ai didi

javascript - React 测试库在初始渲染后未使用 getAllByTestId 找到元素

转载 作者:行者123 更新时间:2023-12-04 07:21:34 28 4
gpt4 key购买 nike

我有一个非常简单的组件,我试图在其中模拟 API 调用以稍微延迟获取一些电影。
我想编写一个测试来测试电影被收集然后渲染到屏幕上。
我正在尝试使用 screen.getAllByTestId这样做,但它总是失败。就好像它没有重新渲染,因此没有得到更新的更改。
我在元素上添加了一个 testid,并且可以在 DOM 中看到它们。
任何人都可以帮助解释为什么在它们出现后找不到它们吗?
enter image description here
这是完整的组件代码...

import './App.css';
import { useEffect, useState } from 'react';

function App() {
const [movies, setMovies] = useState([]);

useEffect(() => {
// simulate API call to get
setTimeout(() => {
const movies = [{ title: 'Titanic' }, { title: 'Back To The Future' }];
setMovies(movies);
}, 1000);
}, []);

return (
<div>
{movies.length > 0 && (
<div>
{movies.map((x) => (
<div data-testid='movies'>{x.title}</div>
))}
</div>
)}
</div>
);
}

export default App;
这是完整的测试代码...
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
render(<App />);
const movieTiles = screen.getAllByTestId('movies');
expect(movieTiles).toHaveLength(2);
});

这是测试的错误
enter image description here

最佳答案

您应该使用 Fake Timers当您的代码使用计时器( setTimeoutsetIntervalclearTimeoutclearInterval )时。
使用jest.advanceTimersByTime(1000)时间提前 1000 毫秒。
不要忘记act()辅助功能:

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. react-dom/test-utils provides a helper called act() that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions:


由于我们运行 setState将提前 1000 毫秒更改组件状态的函数,我们必须将此操作 ( jest.advanceTimersByTime(1000) ) 包装在 act() 中功能。
否则,您将收到警告:

Warning: An update to App inside a test was not wrapped in act(...).


When testing, code that causes React state updates should be wrapped into act(...):


例如。 App.jsx :
import React, { useEffect, useState } from 'react';

function App() {
const [movies, setMovies] = useState([]);

useEffect(() => {
setTimeout(() => {
const movies = [{ title: 'Titanic' }, { title: 'Back To The Future' }];
setMovies(movies);
}, 1000 * 10);
}, []);

return (
<div>
{movies.length > 0 && (
<div>
{movies.map((x, idx) => (
<div key={idx} data-testid="movies">
{x.title}
</div>
))}
</div>
)}
</div>
);
}

export default App;
App.test.jsx :
import { render, screen, act } from '@testing-library/react';
import React from 'react';
import App from './App';

describe('68460159', () => {
test('renders learn react link', async () => {
jest.useFakeTimers();
render(<App />);
act(() => {
jest.advanceTimersByTime(1000 * 10);
});
const movieTiles = screen.getAllByTestId('movies');
expect(movieTiles).toHaveLength(2);
jest.runOnlyPendingTimers();
jest.useRealTimers();
});
});
测试结果:
 PASS  examples/68460159/App.test.jsx (7.878 s)
68460159
✓ renders learn react link (33 ms)

----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
App.jsx | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 8.678 s, estimated 10 s

关于javascript - React 测试库在初始渲染后未使用 getAllByTestId 找到元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68460159/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com