0

我有一个 React 函数组件。我将一个函数作为道具传递给组件,它返回一个承诺。我在一个事件上使用该函数onClick,一旦 promise 得到解决,我就会更改组件的状态。就像是:

import React, { useState } from 'react';

function myComponent({ aPromiseReturningFunction }) {
    const [myState, setState] = useState('12');
    const clickHandler = () => {
      aPromiseReturningFunction().then(() => { setState('123') })
    };

    return <div onClick={ clickHandler }>{myState}</div>
}

在我的测试中:

const myFunc = jest.fn(() => Promise.resolve(true));
const componentWrapper = shallow(<myComponent aPromiseReturningFunction={ myFunc }/>);
componentWrapper.simulate('click');
expect(componentWrapper.text()).toEqual('123');

显然以上失败了,但我还没有找到任何可以解释如何正确测试上述内容的东西。当然,如果我改变了承诺之外的状态,测试就通过了。

有什么建议么?

4

2 回答 2

3

由于click在承诺之后更新状态,也就是异步,我会使用act

import { act } from 'react-dom/test-utils'; // other testing libraries have similar methods that test async events

const myFunc = jest.fn(() => Promise.resolve(true));

it('updates text after onclick', () => {
  const componentWrapper = shallow(<myComponent aPromiseReturningFunction={ myFunc }/>);
  act(() => {
    componentWrapper.simulate('click');
  });

  expect(componentWrapper.text()).toEqual('123');
});
于 2021-09-02T14:41:31.883 回答
0

感谢alextrastero,我最终设法找到了解决方案。

alextrastero 的回答中缺少的是我们应该将act()内部 async/await 括起来,例如:

import { act } from 'react-dom/test-utils'; // other testing libraries have similar methods that test async events

const myFunc = jest.fn(() => Promise.resolve(true));

it('updates text after onclick', async () => {
  const componentWrapper = shallow(<myComponent aPromiseReturningFunction={ myFunc }/>);
  await act(() => {
    componentWrapper.simulate('click');
  });

  expect(componentWrapper.text()).toEqual('123');
});

为了让它工作,我还需要使用这个regenerator-runtime/runtime包。

于 2021-09-02T15:52:52.460 回答