Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test custom hooks in React using JEST, Enzyme?

I have a Custom Hook like below

const useSum = (a = 1, b = 1) => {
  const [sum, setSum] = useState(a + b);

  useEffect(() => {
    setSum(a + b);
  }, [a, b]);

  return sum;
}

I am using this in my funcionat component

const MyFuncComp = () => {
  const sum = useSum(1, 2);
  return (
   <div>{sum}</div>
  );
}

In test case I have it like this

describe('Testing MyFuncComp', () => {
  const myFuncComp = mount(<MyFuncComp />);
  it('should have value of sum', () => {

    const expected = '3';
    const received = myFuncComp.find('div').text();
    expect(received).toEqual(expected);    
  });
})

It's never executing 'useState' or 'useEffect'. Received value is always 'undefined';

like image 900
Paveloosha Avatar asked Nov 27 '20 15:11

Paveloosha


People also ask

Does enzyme support react hooks?

Currently Enzyme doesn't support React Hooks and Alex's answer is correct, but looks like people (including myself) were struggling with using setTimeout () and plugging it into Jest. Below is an example of using Enzyme shallow wrapper that calls useEffect () hook with async calls that results in calling useState () hooks.

Is it a bad idea to test react hooks?

It’s not a bad idea to check that as we dig into testing React hooks. A pretty standard to-do component looks something like this:

Should you use @testing-library/React or @test-library for JavaScript hooks?

But there are definitely more complicated hooks where using @testing-library/react is more useful. Kent C. Dodds is a JavaScript software engineer and teacher. He's Co-Founder and Director of Developer Experience at Remix!

What is the Order of hooks in react hooks?

According to the official documentation, React depends on the order in which hooks are called to associate state and the corresponding useState call. This code breaks the order as the hook will only be called if the conditions are true. This also applies to useEffect and other hooks. Check out the documentation for more details.


Video Answer


1 Answers

I recommend you to use: @testing-library/react-hooks

import { renderHook } from '@testing-library/react-hooks';


describe('Testing MyFuncComp', () => {
  it('should have value of sum', () => {
    const myFuncComp = renderHook(() => useSum(1,2));
    const expected = '3';
    const received = myFuncComp.result.current;
    expect(received).toEqual(expected);    
  });
})

Also I don't think you need enzyme or any lib to test your component, you can use react-dom and react-dom/test-utils

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import MyFunComp from "./MyFunComp";

let container = null;

describe("Card component", () => {
  beforeEach(() => {
    // setup a DOM element as a render target
    container = document.createElement("div");
    document.body.appendChild(container);
  });

  afterEach(() => {
    // cleanup on exiting
    unmountComponentAtNode(container);
    container.remove();
    container = null;
  });

  it("Should render correctly", async () => {
    await act(async () => {
      render(<MyFunComp />, container);
    });
    const div = container.querySelector("div");
    expect(div).toBeTruthy();
    expect(div.textContent).toBe("123");
  });
});
like image 104
lissettdm Avatar answered Oct 18 '22 18:10

lissettdm