0

我在使用 react-native-testing-library 对组件进行单元测试时遇到问题。

我有一个这样的组件:

// components/TestComponent.js
function TestComponent() {
  const [data, setData] = useState();

  useEffect(() => {
    clientLibrary.getData()
      .then((result) => { setData(result.data); } )
      .catch((err) => { //handle error here } )
  }, []);

  render (
    <ListComponent 
      testID={"comp"} 
      data={data})
      renderItem={(item) => <ListItem testID={'item'} data={item} />}
    />
  );
}

我像这样测试它:

// components/TestComponent.test.js

it('should render 10 list item', async () => {
  const data = new Array(10).fill({}).map((v, idx) => ({
      id: `v_${idx}`,
    }));

  const req = jest.spyOn(clientLibrary, 'getData').mockImplementation(() => {
      return Promise.resolve(data);
    });

  const {queryByTestId, queryAllByTestId} = render(
    <TestComponent />,
  );

  expect(await queryByTestId('comp')).toBeTruthy(); // this will pass
  expect(await queryAllByTestId('item').length).toEqual(10); // this will fail with result: 0 expected: 10
}); // this failed

测试将失败/通过

Attempted to log "Warning: An update to TestComponent inside a test was not wrapped in act(...).指向使用setData效果。

我尝试用 包装渲染,用 包装act()断言act(),不模拟 api 调用,将整个测试包装在 中act(),但错误不会消失。

对于这种情况,我已经尝试查看测试库文档/git/q&a,也搜索了 stackoverflow 问题,但我仍然无法使这个测试有效。

谁能指出我解决这个问题的正确方向?

注意:我不是要测试实现细节。我只想测试给定获取结果 X,组件将按预期呈现,即呈现 10 个列表项。

4

1 回答 1

0

您的组件在内部安装期间正在执行异步状态更新,useEffect因此渲染行为具有异步副作用,需要将其包装在await act(async())调用中。请参阅有关数据获取的测试配方文档

你可以在你的测试中尝试这样的事情:

it('should render 10 list item', async () => {
  // Get these from `screen` now instead of `render`
  const { queryByTestId, queryAllByTestId } = screen
  const data = new Array(10).fill({}).map((v, idx) => ({
      id: `v_${idx}`,
    }));

  const req = jest.spyOn(clientLibrary, 'getData').mockImplementation(() => {
      return Promise.resolve(data);
    });

  await act(async () => {
    render(
      <TestComponent />
    );
  })

  expect(await queryByTestId('comp')).toBeTruthy();
  expect(await queryAllByTestId('item').length).toEqual(10);
});

于 2021-09-16T13:58:45.507 回答