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

qyzbxkaa  于 2023-11-15  发布在  Jest
关注(0)|答案(4)|浏览(158)

在我的React.Component示例的componentDidMount中,我有一个fetch()调用,它在响应时调用setState
我可以模拟请求并使用sinon进行响应,但我不知道fetch何时会解析它的promise链。

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

字符串
在我使用jestenzyme进行的测试中:

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,但这并不理想。

eufgjt7s

eufgjt7s1#

最好的解决方案似乎是使用容器模式,并从容器类中传递API数据,并单独测试组件。这允许测试中的组件简单地将API数据作为 prop ,并使其更具可测试性。

vi4fp9gy

vi4fp9gy2#

由于您没有进行任何真实的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);
});

字符串

cnwbcb6i

cnwbcb6i3#

react测试库有一个waitFor函数,非常适合这种情况。
我将给予一个钩子和函数的例子,因为这是当前的react模式。假设你有一个类似于这个的组件:

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测试库文档

von4xj4u

von4xj4u4#

使用nocklink)模拟它,你几乎可以立即使用。还有一个视频教程(link)。不要忘记使用waitFor

test.only('should use API response', async () => {
  nock(BASE_URL)
    .get(`/account/${ACCOUNT_ID}/lists?page=1`)
    .reply(200, listsMockResponse1page);
 const {getByTestId} = render(component);
...

字符串

相关问题