首页 > 解决方案 > 使用 Hook 进行 React 测试在状态更新上不起作用

问题描述

我正在尝试为功能组件编写一个测试用例,该组件使用钩子进行状态更新并从模拟承诺调用中获取数据。

// 功能组件

const MockPage = () => {
  const [mockData, setMockData] = React.useState<IMock[]>([]);
  const mockService = new mockService();

  React.useEffect(() => {
    mockService.getMockData().then((res) => {
      setMockData(res);
    });
  }, []);

  return (
    <div>
      <MockTable mocktData={mockData} />
    </div>
  );
}

这是我编写的测试用例,其中PASSES

 it('renders without crashing', () => {
        mount(<MockPage />);
    });

以下是我编写的FAILS 测试用例

 it('renders without crashing', () => {
       const wrapper =  mount(<MockPage />);
        expect(wrapper.is(MountTable)).toBeDefined();
    });



it('renders without crashing', () => {
           const wrapper =  mount(<MockPage />);
            expect(wrapper.find(MountTable).prop('mockData').toHaveLenght(2);
        }); // assusming the mockData has 2 objects in an array

这里犯了什么错误?有什么遗漏吗?

注意:我也尝试过使用 act() ,但没有成功。

标签: reactjsjestjsenzyme

解决方案


您的数据获取是异步发生的,因此您需要等待承诺解决,然后再检查您的数据。

至少(尽管当您有多个承诺时这并不总是有效),您可以这样做:

const wrapper = mount(<MockPage />);

return Promise.resolve().then(() => {
  expect(...).toBe(true);
});

有一个很棒的库,在不够wait-for-expect时也可以提供帮助:return Promise.resolve().then(...)

import waitForExpect from `wait-for-expect`;

const wrapper = mount(<MockPage />);

return waitForExpect(() => {
  expect(...).toBe(true);
});

推荐阅读