How to use the testing library for React hooks

If you’ve ever written a custom React hook before, you may have noticed how hard it is to test it. Usually, as soon as you call your custom hook, you will come across this error:

Invariant Violation: Hooks can only be called inside the body of a function component.

As suggested by the error, you would need to write a component solely to test your hook.

This is where the react-hooks-testing-library comes in.

React hooks testing library

The react-hooks-testing-library allows you to create a simple test harness for React hooks. It then runs them within the body of a function component.

The library provides helpful utility functions for updating the inputs and retrieving your custom hook’s outputs. The library aims to provide a testing experience as close as possible to natively using your hook from within an actual component.

The library takes care of all the construction, rendering, and interaction of the React component so you can focus on testing your hook.

You can use the hook directly and assert the results.

Installation

npm install --save-dev @testing-library/react-hooks

The minimum supported version of react, react-test-renderer, and react-dom is ^16.9.0.

Code

Let’s look at an example of how to test a custom hook using the react-hooks-testing-library.

We will create a custom hook named useCounter with the count state and increment method:

import { useState, useCallback } from 'react'
function useCounter() {
const [count, setCount] = useState(0)
const increment = useCallback(() => setCount((x) => x + 1), [])
return { count, increment }
}
export default useCounter

To test useCounter, we need to render it using the renderHook function provided by the react-hooks-testing-library.

We then call its increment method by wrapping it in a utility function act.

Finally, use expect to make the assertions.

import { renderHook, act } from '@testing-library/react-hooks'
import useCounter from './useCounter'
test('should increment counter', () => {
const { result } = renderHook(() => useCounter())
act(() => {
result.current.increment()
})
expect(result.current.count).toBe(1)
})

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved