如何模拟反应自定义钩子返回值?
Posted
技术标签:
【中文标题】如何模拟反应自定义钩子返回值?【英文标题】: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, () => ]);
我怎样才能做到这一点?
【问题讨论】:
到目前为止你尝试过什么?你看过 Jest 文档吗? jestjs.io/docs/en/manual-mocks#mocking-user-modules @Timo 看起来......运气不好。我想我可能需要先监视 useClientRect 然后模拟返回。 你试过github.com/testing-library/react-hooks-testing-library吗? 如果你模拟scrollHeight
/clientHeight
而不是模拟钩子呢? ***.com/a/56457850/2071697
【参考方案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");
);
干杯!!如果这有帮助,请善待其他开发者并点赞。
【讨论】:
以上是关于如何模拟反应自定义钩子返回值?的主要内容,如果未能解决你的问题,请参考以下文章