首页 > 解决方案 > 如何在 useEffect 中模拟 fetch 函数?

问题描述

这就是我在useEffect钩子中的函数的外观:

useEffect(() => {
    const getImages = async () => {
      try {
        setIsLoading(true);
        const response = await fetch(GET_RECENT_IMAGES_API_URL(pageNumber));

        if (!response.ok) {
          throw new Error("Network response was not ok");
        }

        const imageData = await response.json();

        setIsLoading(false);

        const appImaegDataArray: CoreImageData[] = imageData.photos.photo.map(
          (image: ResponseImageData) => {
            const { id, server, secret, title, ownername } = image;

            const coreImageDataObj: CoreImageData = {
              id,
              server,
              secret,
              title,
              ownername,
              isFavorite: checkIfFavorited(id),
            };

            return coreImageDataObj;
          }
        );
        setAllImages((prevAllImagesState) => {
          const newestImagesArray = [
            ...prevAllImagesState,
            ...appImaegDataArray,
          ];
          return getUniqueImagesArray(newestImagesArray);
        });

        setHasMore(imageData.photos.pages > pageNumber);
      } catch (error) {
        console.error(error);
        setIsLoading(false);
      }
    };
    getImages();
    // eslint-disable-next-line
  }, [pageNumber]);

这是我模拟请求的方法:

global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () =>
      Promise.resolve({
        photos: {
          pages: 10,
          photo: [
            {
              id: "51159068217",
              owner: "50123236@N03",
              secret: "dda285148c",
              server: "65535",
              farm: 66,
              title: "Blythe a Day May 5–Magical",
              ispublic: 1,
              isfriend: 0,
              isfamily: 0,
            },
          ],
        },
      }),
  })
) as jest.Mock;

describe("<ImageList />", () => {
  it("loads all images on mount", async () => {
    render(<ImageList isViewFavoriteImages={false} />);
    await waitFor(() =>
      expect(screen.getByText("Blythe a Day May 5–Magical")).toBeInTheDocument()
    );
  });
});

但是,这样做时,我得到一个错误并且测试失败。这是失败测试的输出: 在此处输入图像描述

修复测试的最佳方法是什么?

标签: reactjsjestjsreact-testing-library

解决方案


global.fetch = jest.fn(() => ({
  json: ...,
  ok: true,
  status: 200,
})

虽然我建议不要模拟 fetch。而是将其提取到服务方法并模拟它..?

// my-service.js

export const fetchFoo = () => {
  return fetch(...)
}

// my-test.spec.js

jest.mock('./my-service', () => jest.fn(() => Promise.resolve('some-value'));

推荐阅读