6

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
    });
  });
dagda1
  • 26,856
  • 59
  • 237
  • 450

2 Answers2

7

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)
})
Matthieu Libeer
  • 2,286
  • 1
  • 12
  • 16
  • Please have a look at this i am facing same problem : https://stackoverflow.com/questions/73977384/the-module-factory-of-jest-mock-is-not-allowed-to-reference-any-out-of-scope – user2028 Oct 07 '22 at 08:44
4

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>
bozdoz
  • 12,550
  • 7
  • 67
  • 96