如何在React/Jest中模拟自定义hook的返回数据?

6

我有一个名为useFetch的自定义钩子,它只是获取数据并将其返回,在我的组件测试中,我想模拟这个钩子以返回一些虚假数据,我该如何做到这一点?

import React, { useEffect, useState } from 'react';

export const useFetch = (url: string) => {
  const [data, setData] = useState();

  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url);
        const json = await res.json();
        setData(json);
      } catch (error) {
        console.log(error);
      }
    };

    fetchData();
  }, [url]);

  return data;
};

const App = () => {
  const config = useFetch(`/api/url`);

  return (
    <div></div>
  );
};

export default App;

有没有办法在我的Jest测试中模拟 useFetch,以便将 const config 设置为一些虚拟数据?


这个回答解决了你的问题吗?如何使用Jest在Node.js中模拟fetch函数? - j3ff
并不是在嘲笑fetch函数,我只是想嘲笑钩子的返回值。 - offlineanton
在我看来,你不应该嘲笑钩子,因为它内部的代码不会被你的测试覆盖。模拟fetch调用是更好的选择,这样你的测试也可以覆盖钩子的实现,从而确保没有错误或不良行为。 - j3ff
2个回答

2
我建议将你的钩子放在一个单独的文件中,比如说 useFetch.js 包含以下内容:
import { useEffect, useState } from "react";

export const useFetch = (url: string) => {
  const [data, setData] = useState();

  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url);
        const json = await res.json();
        setData(json);
      } catch (error) {
        console.log(error);
      }
    };

    fetchData();
  }, [url]);

  return data;
};


保持您的应用程序组件文件如下所示:
import React from "react";

import { useFetch } from "./useFetch";


const App = () => {
  const config = useFetch(`/api/url`);

  return (
    <div></div>
  );
};

export default App;


使用以上分割符,您可以轻松地模拟您的钩子,例如测试文件如下所示。
import React from "react";
import { render } from "@testing-library/react";
import App from "./App";


// mock config
const mockConfig = {
    data: "mock data"
};

// this will mock complete file, we have provided mock implementation
// for useFetch function
jest.mock("./useFetch", () => ({
    useFetch: () => mockConfig
}));

test("should render with mock useFetch", () => {
    const { getByText } = render(<App />);
    // test logic goes here
});



假设所有文件都在同一个目录中。

0
你可以尝试模拟fetch库。 在测试设置中:
global.fetch = jest.fn()

然后在你的测试中:

global.fetch.mockResolvedValue({ json: () => ({ data: "" })})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接