reactjs 如何模拟自定义钩子返回值?

niwlg2el  于 2022-12-22  发布在  React
关注(0)|答案(3)|浏览(150)

下面是我的自定义钩子:

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, () => {}]);

我怎样才能做到这一点?

jvidinwx

jvidinwx1#

将钩子作为一个模块加载,然后模拟这个模块:

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

mock应该在测试fn之外的文件顶部调用,因此我们将只使用一个数组作为模拟值。
如果要在不同的测试中使用不同的值模拟钩子:

import * as hooks from 'module_name';

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

blmhpbnm2#

对于遇到TS2339: Property 'mockReturnValue' does not exist on type错误消息的打字脚本用户,添加这个答案。现在有一个jest.mockedFunction,你可以用Type defs调用它来模拟(它是ts-jest/utils mocked函数的一个端口)。

import useClientRect from './path/to/useClientRect';

jest.mock('./path/to/useClientRect');

const mockUseClientRect = useClientRect as jest.MockedFunction<typeof useClientRect>

describe("useClientRect", () => {
  it("mocks the hook's return value", () => {
    mockUseClientRect.mockReturnValue([300, 200, () => {}]);
    // ... do stuff
  });

  it("mocks the hook's implementation", () => {
    mockUseClientRect.mockImplementation(() => [300, 200, () => {}]);
    // ... do stuff
  });
});
oxosxuxt

oxosxuxt3#

这是相当棘手的,有时开发人员会被这个库搞糊涂,但一旦你习惯了它,它就变得小菜一碟了。几个小时前我遇到过类似的问题,我分享了我的解决方案,让你轻松地得到你的解决方案。
我的自定义钩子:

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");
  });
}

相关问题