Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 防止";不受法案(……)的约束。”;状态更新失败时发出Jest警告';不影响用户界面_Javascript_Reactjs_Jestjs_React Testing Library_Testing Library - Fatal编程技术网

Javascript 防止";不受法案(……)的约束。”;状态更新失败时发出Jest警告';不影响用户界面

Javascript 防止";不受法案(……)的约束。”;状态更新失败时发出Jest警告';不影响用户界面,javascript,reactjs,jestjs,react-testing-library,testing-library,Javascript,Reactjs,Jestjs,React Testing Library,Testing Library,我试图找出是否有一种方法可以防止Jest/测试库在导致警告发生的状态更新后没有任何可断言的内容时抛出“not wrapped in act(…)”警告,或者是否应该忽略此警告 假设我有一个简单的组件: import React, {useEffect, useState} from 'react'; import {getData} from 'services'; const MyComponent = () => { const [arr, setArr] = useState(

我试图找出是否有一种方法可以防止Jest/测试库在导致警告发生的状态更新后没有任何可断言的内容时抛出“not wrapped in act(…)”警告,或者是否应该忽略此警告

假设我有一个简单的组件:

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;
此测试将通过,但我将得到“not wrapped in act(…)”警告,因为测试将在
getData()
有机会完成之前完成

在本例中,来自
getData()
的响应将
arr
设置为与我最初在组件顶部设置的值相同的值(空数组)。因此,在异步函数完成后,我的UI不会改变——我仍然在看一段写着“无数组项”的文字——因此我没有任何可以断言的东西可以等待状态更新完成

我可以
expect(getData).tohaveencalledtimes(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();
});
it('renders',async()=>{
getData.mockResolvedValue({items:[]});
render();
expect(screen.getByText('no array items')).toBeInTheDocument();
等待新的承诺(resolve=>setTimeout(resolve,2000));
expect(screen.getByText('no array items')).toBeInTheDocument();
});
但这似乎没有什么帮助,老实说,我也不知道为什么

有没有办法通过只修改测试来处理这种情况?

我相信我可以通过重构MyComponent来解决这个问题,例如,将
arr
作为一个道具传递给MyComponent,并将
getData()
调用移动到父组件,或者创建一些仅用于测试的自定义道具,从而完全跳过
getData()
调用,但我不想仅仅为了避免测试中的警告而修改组件


我使用的是v11.2.2。

您可以使用
findByText
getByText
waitFor
的组合)来确保在断言解析时发生所有更新

it('renders',async()=>{
getData.mockResolvedValue({items:[]});
render();
expect(wait screen.findByText('no array items')).toBeInTheDocument();
});

谢谢。我知道
findBy
并且已经大量使用了它,但我想我不知道它一定会等待状态更新。我提到的文档()使它看起来像是在等待异步DOM更改,但在这种情况下,DOM实际上没有更改(即使组件的呈现函数再次被调用),所以我想我认为这是行不通的。今后我必须记住这一点:)
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();
});