Jest test fails on a react component which uses react-hooks-form with sharing refs

Viewed 200

Here is the abstract version of my component

const Test = () => {
  const { register } = useFormContext();
  const mRef = useThirdpartyHook(); // Third party hook returns a ref
  const { ref, ...rest } = register('test');
  return (
    <input
      type="text" 
      name="test" 
      {...rest} 
      ref={(e) => {
        ref(e); 
        mRef.current = e;
      }}
    />
  );
};

export default Test;

Test case

import React from 'react';
import { render } from '@testing-library/react';
import { FormProvider } from 'react-hook-form';
import Test from './Test';

describe('<Test> component', () => {
  it('renders default correctly', () => {
    const wrapper = render(
      <FormProvider
        {...{ register: () => jest.fn() }}>
        <Test />
      </FormProvider>
    );
        
    expect(wrapper.baseElement).toMatchSnapshot();
  });
});

Executing this test throws an error as given below.

<Test> component › renders default correctly

    TypeError: ref is not a function
                     ref={(e) => {
                         ref(e);
                         ^
                         mRef.current = e;
                     }}

I tried to mock the ref as function but it didn't help. It would be great if anyone can throw some insights.

1 Answers

register is a function that returns props the input needs. You are mocking the register function, but it still needs to return everything the component is consuming or passing on. Specifically it seems you need to return a ref function for what is returned by the useFormContext hook.

Example:

describe('<Test> component', () => {
  it('renders default correctly', () => {
    const registerMock = () => ({
      ref: jest.fn(),
      .... mock other necessary bits here
    });

    const wrapper = render(
      <FormProvider
        {...{ register: registerMock }}
      >
        <Test />
      </FormProvider>
    );
        
    expect(wrapper.baseElement).toMatchSnapshot();
  });
});
Related