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.
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();
});
});