等待 fetch() 使用 Jest 进行 React 测试解析?

问题描述 投票:0回答:4

componentDidMount
实例的
React.Component
中,我有一个
fetch()
调用,该调用响应调用
setState

我可以模拟请求并使用

sinon
进行响应,但我不知道 fetch 何时会解决它的承诺链。

componentDidMount() {
  fetch(new Request('/blah'))
    .then((response) => {
      setState(() => {
        return newState;
      };
    });
}

在我的测试中使用

jest
enzyme
:

it('has new behaviour from result of set state', () => {
  let component = mount(<Component />);

  requests.pop().respond(200);

  component.update() // fetch() has not responded yet and
                     // thus setState has not been called yet
                     // so does nothing

  assertNewBehaviour(); // fails

  // now setState occurs after fetch() responds sometime after
});

我需要刷新 Promise 队列/回调队列或类似的东西吗?我可以对 newBehaviour 进行超时重复检查,但这不太理想。

javascript reactjs unit-testing jestjs enzyme
4个回答
1
投票

最好的答案似乎是使用容器模式,并从具有分离关注点的容器类传递 API 数据,并分别测试组件。这使得被测组件可以简单地将 API 数据作为 props,并使其更具可测试性。


0
投票

由于您没有进行任何真正的 api 调用或其他耗时的操作,因此异步操作将在可预测的短时间内解决。

因此您只需稍等片刻即可。

it('has new behaviour from result of set state', (done) => {
  let component = mount(<Component />);
  requests.pop().respond(200);

  setTimeout(() => {
    try {
      component.update();
      assertNewBehaviour();
      done();
    } catch (error) {
      done(error);
    }
  }, 1000);
});

0
投票

React 测试库有一个

waitFor
功能,非常适合这种情况。

我将给出一个带有钩子和函数的示例,因为这是当前的反应模式。假设您有一个与此类似的组件:

export function TestingComponent(props: Props) {
    const [banners, setBanners] = useState<MyType>([]);

    React.useEffect(() => {
        const response = await get("/...");
        setBanners(response.banners);
    }, []);

    return (
        {banners.length > 0 ? <Component> : </NoComponent>}
    );
}


现在您可以编写这样的测试,以确保设置横幅时

Component
被渲染

test("when the banner matches the url it renders", async () => {
        const {container} = render(<TestingComponent />);
        await waitFor(() => {expect(...).toBe(...)});
    });

waitFor
将等待函数中的条件满足后再继续。有一个超时,如果在 X 时间内不满足条件,测试就会失败。 查看 React 测试库文档以获取更多信息


0
投票

使用

nock
链接)模拟它,您几乎可以立即使用。还有视频教程(链接

test.only('should use API response', async () => {
  nock(BASE_URL)
    .get(`/account/${ACCOUNT_ID}/lists?page=1`)
    .reply(200, listsMockResponse1page);
 const {getByTestId} = render(component);
...
© www.soinside.com 2019 - 2024. All rights reserved.