Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to test a react hook that can have a ref of an html element passed to it

I have a custom hook that can have an optional ref passed to it as a property of an object that the hook takes as an argument:

export const useShortcuts = ({ ref }) => {
  useEffect(() => {
    const trapper = new mousetrap(ref.current);

The code works but I am now trying to write tests for this using react-testing-library and the @testing-library/react-hooks library.

I am using renderHook from @testing-library/react-hooks but I don't know how to create the ref or mock the ref outside of a component.

  it('should create shortcuts with no ref', () => {
    const ref = ?????  // how do I do this

    const { result } = renderHook(() => useShortcuts({ ref }), {
      initialProps: true
    });
  });
like image 917
dagda1 Avatar asked Mar 03 '23 15:03

dagda1


2 Answers

You can create refs with React.createRef

const ref = React.createRef()

Full working example below

import React, { useEffect } from 'react'
import { renderHook } from '@testing-library/react-hooks'

const useShortcuts = ({ ref }) => {
  useEffect(() => {
    ref.current = 1
  }, [])
}


it('works', () => {
  const ref = React.createRef()

  const { result } = renderHook(() => useShortcuts({ ref }))
  expect(ref.current).toEqual(1)
})
like image 193
Matthieu Libeer Avatar answered Apr 28 '23 18:04

Matthieu Libeer


A typesafe way to do this (since in TypeScript createRef returns a readonly object), would be to just ditch the createRef idea and just create an object with a current property:

it('should create shortcuts with no ref', () => {
  const ref = { current: undefined }

  const { result } = renderHook(() => useShortcuts({ ref }), {
    initialProps: true
  });
});

Or if you want to pass an element:

const elem = document.createElement('div');
const ref = { current: elem };

The latter should suffice as a type for TypeScript if the hook is expecting:

ref: React.RefObject<HTMLElement>
like image 32
bozdoz Avatar answered Apr 28 '23 17:04

bozdoz