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

这是我定制的钩子:

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

我怎么才能做到呢?

92417 次浏览

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

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

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

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

import * as hooks from 'module_name';


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

这非常棘手,有时候开发人员会被库搞糊涂,但是一旦您习惯了它,它就变成了小菜一碟。几个小时前我也遇到过类似的问题,现在我把我的解决方案分享给大家,让你们能够很容易地推导出你们的解决方案。

我的定制 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 };
};

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

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

干杯! ! 如果这有帮助,请善待其他开发人员,并给它竖起大拇指。

为遇到 TS2339: Property 'mockReturnValue' does not exist on type错误消息的打字机用户添加此答案。现在可以使用 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
});
});