react-hook-form V7: how unit test a MUI component with jets?

Viewed 1829

I have the following component that takes control as an argument:

const TexInputMUI = (props) => {
  const { control, variant, margin, ...rest } = props
  return (
    <Controller
      name='myMUItf'
      defaultValue=''
      control={control}
      render={({ field }) => (
        <TextField
          {...field}
          variant={variant}
          margin={margin}
          label='A simple MIU text field'
          {...rest}
        />
      )}
    />
  )
}

And, I have a simple test that wants to check whether the component rendered or not

test("Render text input without crashing", () => {
   const { getByLabelText } = render(<TextInputMUI control={}/>);
   const textField = getByLabelText(/A simple MIU text field/);
});

Now, the problem is that I don't know how to pass control as a argument in my test.

Can anyone help?

1 Answers

For future reference, the solution to the question above has two three.

First, instead of passing control down as a prop to a nested component, you can access the form context with the use of useFormContext. Documentation here.

    imports ...
    const schema = yup.object().shape({...});
    function App() {
      const methods = useForm({
        resolver: yupResolver(schema)
      });
      const { register, handleSubmit, formState: { errors }} = methods;
    
      return (
        <FormProvider {...methods}>
          <form onSubmit={handleSubmit((data) => console.log(data))}>
            <NestedInput/>
          </form>
        </FormProvider>
      );
    }

Second, you need to refactor the nested component to access the form context as follow:


    imports . . . 
    import { Controller, useFormContext } from 'react-hook-form'
    
    const NestedMUIinput = () => {
      const { control, ...rest } = useFormContext()
    
      return (
        <Controller
          name='nestedMUIinput'
          defaultValue=''
          control={control}
          render={({ field }) =>
            <TextField
              {...field}
              variant='outlined'
              margin='normal'
              fullWidth
              label='Nested input:'
              {...rest}
            />}
        />
      )

Third, in your test file, you need to wrap the <NestedMUIinput /> with the Provider.

imports . . .
import { useForm, FormProvider } from 'react-hook-form'
import NestedMUIinput from './NestedMUIinput'

const WrapperForm = ({ children }) => {
  const methods= useForm()
  return (
    <FormProvider {...methods}>
      {children}
    </FormProvider>
  )
}

test('Render text input without crashing', () => {
  const { getByLabelText } = render(<WrapperForm><NestedMUIinput /></WrapperForm>)
  const textField = getByLabelText(/Nested input:/)
})
Related