使用try / catch进行useEffect挂钩的测试

时间:2020-05-27 08:06:58

标签: reactjs jestjs react-hooks enzyme use-effect

在获取数据请求拒绝时,我需要测试UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2),但我不明白为什么未捕获到错误,我收到了以下错误:export const Container = ({fetchFirstAsset, fetchSecondAsset}) => { const [status, setStatus] = useState(null); async function fetchAssets() { setStatus(IN_PROGRESS); try { await fetchFirstAsset(); await fetchSecondAsset() setStatus(SUCCESS); } catch { setStatus(FAILURE); } } useEffect(() => { fetchAssets(); }, []); .... };

我有这样的情况:

import {mount} from 'enzyme';
import {act} from 'react-dom/test-utils';

const fetchFirstAsset = jest.fn();
const fetchSecondAsset = jest.fn();

it('should render without errors', async () => {
  fetchFirstAsset.mockReturnValueOnce(Promise.resolve());
  fetchSecondAsset.mockReturnValueOnce(Promise.reject());
  let component;

  await act(async () => {
    component = mount(
      <Container
        fetchFirstAsset={fetchFirstAsset}
        fetchSecondAsset={fetchSecondAsset}
      />
    );
  });

  expect(fetchSomething).toHaveBeenCalled();
});

并像这样测试:

fetchSomething

如果我测试用Promise.resolve()解决Promise.reject()的情况下一切正常,并且测试正确,但是当我尝试catch来测试unhandled promise rejection情况时,则出现此错误没有被捕获,我有useState。 (为什么代码看起来像这样:在应用程序的其他地方,我使用redux来处理状态更改,因此对catch的测试很容易,但是在一个地方,我需要为组件获取3种不同的资产,因此我决定使用useState,因为从redux提取3种不同的状态并将其组合起来会很丑陋,我认为与{{1}}比较干净)

预先感谢您的帮助! :)

2 个答案:

答案 0 :(得分:0)

您需要这样编写catch块:

catch (e) {
     // can do something with e in here
      setStatus(FAILURE);
    }

答案 1 :(得分:0)

我有一个相同的问题,即在useEffect()中使用try / catch子句不起作用。我进行了几次搜索,看来这是一个潜在的错误,请看一下:

https://github.com/testing-library/react-hooks-testing-library/issues/305

也就是说,我能够按以下方式解决该问题:

故障示例:

useEffect(() => {
  try {
      invokeMyAsyncFunction();  
      setStatus(SUCCESS);
  } catch (e) {
      setStatus(FAILURE);   // <== will not be invoked on exception!!
  }
}

成功示例:

useEffect(() => {
  invokeMyAsyncFunction()
     .then((response:any) => {
        setStatus(SUCCESS);
     })
     .catch((e) => {
        setStatus(FAILURE);   // <== this **WILL** be invoked on exception
     });
}