【问题标题】:How to mock react custom hook returned value?如何模拟反应自定义钩子返回值?
【发布时间】:2020-06-01 19:57:54
【问题描述】:

这是我的自定义钩子:

  export function useClientRect() {
    const [scrollH, setScrollH] = useState(0);
    const [clientH, setClientH] = useState(0);
    const ref = useCallback(node => {
      if (node !== null) {
        setScrollH(node.scrollHeight);
        setClientH(node.clientHeight);
      }
    }, []);
    return [scrollH, clientH, ref];
  }
}

我希望每次调用它时,它都会返回我的值。喜欢:

jest.mock('useClientRect', () => [300, 200, () => {}]);

我怎样才能做到这一点?

【问题讨论】:

标签: reactjs jestjs react-hooks react-testing-library


【解决方案1】:

将钩子作为模块加载。然后模拟模块:

jest.mock('module_name', () => ({
    useClientRect: () => [300, 200, jest.fn()]
}));

mock 应该在 test fn 之外的文件之上调用。因此,我们将只有一个数组作为模拟值。

如果你想在不同的测试中用不同的值来模拟钩子:

import * as hooks from 'module_name';

it('a test', () => {
    jest.spyOn(hooks, 'useClientRect').mockImplementation(() => ([100, 200, jest.fn()]));
    //rest of the test
});

【讨论】:

  • 上帝之母,指出它需要位于顶部是有帮助的 - 不知何故,在我看过的其他十几个教程中没有人提到这一点
  • 对我来说,它给出的错误是“useClientRect 不是一个未定义的函数”
  • @MuhammadHaseeb 您需要将 useClientRect 替换为您的钩子名称。在这个例子中,钩子返回一个需要模拟的数组。
  • @muhammad-haseeb 您需要将数组替换为模拟对象。在您的代码 console.log 中,您的钩子返回的值并替换数组,如:jest.spyOn(hooks, 'useYourHookName').mockImplementation(() => ({a: 100, b: 200, c: jest.fn()}));.
  • @Mohammad Kermani 当你有一个钩子文件时,它类似于'../folder_name/hook_file_name.ts'。当你从 npm 库中模拟一个钩子时,它将是 npm 库的名称。
【解决方案2】:

嗯,这很棘手,有时开发人员会对库感到困惑,但一旦你习惯了它,它就会变得轻而易举。几个小时前我遇到了类似的问题,我正在分享我的解决方案,以便您轻松获得解决方案。

我的自定义 Hook:

  import { useEffect, useState } from "react";
    import { getFileData } from "../../API/gistsAPIs";
    
    export const useFilesData = (fileUrl: string) => {
      const [fileData, setFileData] = useState<string>("");
      const [loading, setLoading] = useState<boolean>(false);
      useEffect(() => {
        setLoading(true);
        getFileData(fileUrl).then((fileContent) => {
          setFileData(fileContent);
          setLoading(false);
        });
      }, [fileUrl]);
    
      return { fileData, loading };
    };

我的模拟代码: 请将此模拟包含在测试函数之外的测试文件中。 注意:注意mock的返回对象,它应该与预期的响应匹配

const mockResponse = {
  fileData: "This is a mocked file",
  loading: false,
};
jest.mock("../fileView", () => {
  return {
    useFilesData: () => {
      return {
        fileData: "This is a mocked file",
        loading: false,
      };
    },
  };
});

完整的测试文件是:

import { render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import FileViewer from "../FileViewer";

const mockResponse = {
  fileData: "This is a mocked file",
  loading: false,
};
jest.mock("../fileView", () => {
  return {
    useFilesData: () => {
      return {
        fileData: "This is a mocked file",
        loading: false,
      };
    },
  };
});

describe("File Viewer", () => {
  it("display the file heading", async () => {
    render(<FileViewer fileUrl="" filename="regex-tutorial.md" className="" />);
    const paragraphEl = await screen.findByRole("fileHeadingDiplay");
    expect(paragraphEl).toHaveTextContent("regex-tutorial.md");
  });
}

干杯!!如果这有帮助,请善待其他开发者并点赞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-15
    • 2023-02-07
    • 1970-01-01
    • 2021-11-22
    • 2020-08-20
    • 2020-06-19
    • 2020-08-15
    • 2021-01-26
    相关资源
    最近更新 更多