Preventing quot;not wrapped in act(...)quot; Jest warning when state update doesn#39;t affect UI(当状态更新不影响用户界面时,防止未包装在动作(...)中的Jest警告(C))
问题描述
我正在尝试找出是否有方法可以防止在导致警告发生的状态更新后没有断言时,由Jest/Testing-Library引发的警告中没有包装";,或者我是否应该直接忽略此警告。
假设我有这样一个简单的组件:
import React, {useEffect, useState} from 'react';
import {getData} from 'services';
const MyComponent = () => {
const [arr, setArr] = useState([]);
useEffect(() => {
(async () => {
const {items} = await getData();
setArr(items);
})();
}, []);
return (
<div>
{!(arr.length > 0) && <p>no array items</p>}
{arr.length > 0 && (
<ul>
{arr.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</div>
);
};
export default MyComponent;
假设我只想测试一下,即使getData()
没有为我返回任何数据,此组件也可以正常呈现。
所以我有一个这样的测试:
import React from 'react';
import {getData} from 'services';
import {render, screen} from 'testUtils';
import MyComponent from './MyComponent';
jest.mock('services', () => ({
getData: jest.fn(),
}));
it('renders', () => {
getData.mockResolvedValue({items: []});
render(<MyComponent />);
expect(screen.getByText('no array items')).toBeInTheDocument();
});
此测试将通过,但我将得到&out in act(...)";警告,因为测试将在getData()
有机会完成之前完成。
getData()
的响应将arr
设置为与我最初在组件顶部设置的值(空数组)相同的值。因此,在Async函数完成后,我的UI不会更改--我仍然在查看一个段落,上面写着&"没有数组项&"--所以我实际上没有什么可以断言的东西,可以等待状态更新完成。
我可以expect(getData).toHaveBeenCalledTimes(1)
,但这不会等待在函数调用后实际更新状态。
我已尝试在测试中任意暂停,以便有时间使setArr(items)
发生:
it('renders', async () => {
getData.mockResolvedValue({items: []});
render(<MyComponent />);
expect(screen.getByText('no array items')).toBeInTheDocument();
await new Promise(resolve => setTimeout(resolve, 2000));
expect(screen.getByText('no array items')).toBeInTheDocument();
});
但这似乎没有帮助,老实说,我也不确定为什么。
是否有办法通过仅修改测试来处理此情况?
我确信我可以通过重构MyComponent来解决这个问题,例如,通过将arr
作为道具传递给MyComponent并将getData()
调用移动到父组件,或者创建一些仅用于测试的自定义道具来完全跳过getData()
调用,但我不想纯粹为了避免测试中的警告而修改组件。
我使用的是testing-library/reactv11.2.2。
推荐答案
您可以使用findByText
(getByText
和waitFor
的组合)确保在断言解析时发生所有更新。
it('renders', async () => {
getData.mockResolvedValue({items: []});
render(<MyComponent />);
expect(await screen.findByText('no array items')).toBeInTheDocument();
});
这篇关于当状态更新不影响用户界面时,防止未包装在动作(...)中的Jest警告(&C)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:当状态更新不影响用户界面时,防止未包装在动
基础教程推荐
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- 直接将值设置为滑块 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- Chart.js 在线性图表上拖动点 2022-01-01
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01