The error message "Invalid hook call. Hooks can only be called inside of the body of a function component" occurs when you try to use React hooks (such as useState, useEffect, etc.) outside of a function component or in a place where hooks are not allowed, like a regular function, a class component, or a condition statement.

When unit testing a custom hook, you need to ensure that you are calling the hook inside a functional component or a test function that mimics a functional component. Additionally, you should use testing utilities provided by testing libraries, like react-hooks-testing-library, to render the hook in a test environment.

Here's an example of how to properly unit test a custom hook using react-hooks-testing-library:

Assuming you have a custom hook named useCustomHook:

// useCustomHook.js import { useState, useEffect } from 'react'; function useCustomHook() { const [count, setCount] = useState(0); useEffect(() => { // Some side effect logic... return () => { // Cleanup logic... }; }, []); const increment = () => { setCount((prevCount) => prevCount + 1); }; return { count, increment }; } export default useCustomHook;

To test the useCustomHook:

  1. Install Testing Dependencies: Make sure you have installed the required testing libraries.

    npm install --save-dev @testing-library/react-hooks
  2. Write the Test: Create a test file for your custom hook and use renderHook from @testing-library/react-hooks to test it.

// useCustomHook.test.js import { renderHook, act } from '@testing-library/react-hooks'; import useCustomHook from './useCustomHook'; test('useCustomHook should increment the count', () => { const { result } = renderHook(() => useCustomHook()); // Initially, the count should be 0 expect(result.current.count).toBe(0); // Call the increment function act(() => { result.current.increment(); }); // After the increment, the count should be 1 expect(result.current.count).toBe(1); });
  1. Run the Test: Run your test using your testing framework (e.g., Jest).

    jest useCustomHook.test.js

The renderHook function from @testing-library/react-hooks takes a function that calls your custom hook and returns an object (result) with the values returned from your hook (e.g., result.current.count, result.current.increment). The act function is used to wrap the call to result.current.increment() to ensure that the state updates are correctly processed during testing.

By following this approach, you can properly unit test your custom hook while ensuring that you call hooks inside the body of a functional component, as required by React.

Have questions or queries?
Get in Touch