Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock react custom hook returned value?

Here is my custom hook:

  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];   } } 

I want each time that it is called, it return my values. like:

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

How can I achieve this?

like image 779
Homa Avatar asked Feb 17 '20 20:02

Homa


People also ask

How do you mock custom Hooks in React?

mock with the module name and the function to mock the useClientRect hook with a function that returns the mocked values of the hook. import * as hooks from 'module_name'; it('a test', () => { jest. spyOn(hooks, 'useClientRect'). mockImplementation(() => ([100, 200, jest.

Do React Hooks return a value?

React hooks are not required to return anything.

Can custom Hooks return component?

As seen in the code examples, using hooks to encapsulate shared logic is a good start, but we can keep exploring more. Inspired by the concept of “partial application”, we can try to return a component with props that have been partially bound from a custom hook.


2 Answers

Load the hook as a module. Then mock the module:

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

mock should be called on top of the file outside test fn. Therefore we are going to have only one array as the mocked value.

If you want to mock the hook with different values in different tests:

import * as hooks from 'module_name';  it('a test', () => {     jest.spyOn(hooks, 'useClientRect').mockImplementation(() => ([100, 200, jest.fn()]));     //rest of the test });  
like image 180
Homa Avatar answered Sep 30 '22 02:09

Homa


Well, this is quiet tricky and sometimes developers get confused by the library but once you get used to it, it becomes a piece of cake. I faced similar issue a few hours back and I'm sharing my solution for you to derive your solution easily.

My custom 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 };     }; 

My mock code: Please include this mock in the test file out side of your test function. Note: Be careful about the return object of mock, it should match with the expected response

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

complete test file would be:

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

Cheers!! and if this is helpful please be kind to the other developers and give it a thumbs up.

like image 37
murtaza salim Avatar answered Sep 30 '22 02:09

murtaza salim