首页 > 解决方案 > React/Jest - 有没有办法在渲染之前等待模拟解决

问题描述

在我的反应组件中,默认情况下我将加载设置为 true,然后在返回时将加载设置为 false 的 fetch。当我返回我的 jsx 代码时,我会检查{! loading &&哪个有效,但在我的测试中,fetch 被模拟并调用,但它首先调用渲染,因此它不会渲染组件。

test('App component renders and contains prop given to it', async () => {
  jest.spyOn(window, 'fetch').mockResolvedValue({
    json: jest.fn().mockResolvedValue({ value: 'test' }) as Partial<Response>,
  } as Response);

  await act(async () => {
    const testProp = 'my test';

    const { container, getByText } = render(<App testProp={testProp} />);

    const testPropElement = getByText(testProp);
    console.log('test2');

    expect(testPropElement).toBeInTheDocument();
  });
});

获取看起来像:

fetch(`/api/url`)
      .then((response) => response.json())
      .then((data) => {
        console.log('test1');
        setLoading(false);
      });

当我通过控制台查看事情的顺序时,它肯定会通过 mockResolvedValue 并在“test2”之后显示“test1”。

有人有什么想法吗?谢谢您的帮助。

标签: javascriptreactjsjestjs

解决方案


您正在观察这一点,因为您的 fetch 模拟(和 fetch 本身)返回 Promise,您没有在测试中解析它,而是 Jest 在完成后自动为您解析它。您想在期望之前解决它,以便它可以进行then回调、更改状态并重新渲染组件。

React-testing-library(我看到你正在使用)为此场合提供实用功能:waitFor。它只会等待你的承诺解决和元素出现。

或者,您可以使用findByText,您可以使用它await(基本上只是函数的一个promisified版本getBy*),它也可以像上面那样做。


推荐阅读