Testing react hooks

Published on

There isn't any special about a React component that uses a hook. The hook might use state (useState()) or wrap code in useEffect() but in most cases you could probably inline the hook in the component.

But, even through there isn't much special about them... how do you test React hooks?

Table of Contents

React Testing Library is the most popular way to test React so i'll focus on using it.

Use renderHooks from @testing-library

If you had this custom hook:

import { useState, useCallback } from 'react'

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

and you wanted to test it by itself, you can use the renderHook helper

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

test('should use counter', () => {
  const { result } = renderHook(() => useCounter())

  expect(result.current.count).toBe(0)
  expect(typeof result.current.increment).toBe('function')
})

test('should increment counter', () => {
  const { result } = renderHook(() => useCounter())

  act(() => {
    result.current.increment()
  })

  expect(result.current.count).toBe(1)
})

How to mock useState()

I don't think this is a good idea, but sometimes you have to work around awkward to test components.

One way to mock useState() is to import it in your component via React.useState (import React from 'react' and const [a, setA] = React.useState(false))

Then you can mock it as normal in jest jest.spyOn(React, 'useState').mockReturnValue([fakeA, setFakeA])

note: some examples from official docs