How to mock the elements of react-hook-form when testing with react-testing-library?
Asked Answered
D

3

6

Having a basic component which uses react-hook-form:

const { handleSubmit, reset, control } = useForm({ resolver: yupResolver(schema) });

...

  <MyComponent
    title='title'
    open={isOpened}
    control={control}
  />

This component has 3 props, title - a string, open - a function, control - no idea what is it, all of them mandatory.

So, when writing a test for it I got stuck here:

import { render } from '@testing-library/react';

import '@testing-library/jest-dom';
import MyComponent from './my-component';

describe('MyComponent', () => {
  const title = 'title';
  it('should render successfully', () => {
    const { baseElement, getByText } = render(
      <TaskModal
        title={title}
        open={jest.fn()}
        control={} // what should be written here?
      />
    );
    expect(baseElement).toBeTruthy();
    expect(getByText(title)).toBeTruthy();
  });

How can control be mocked for this test?

Dextrorse answered 21/12, 2021 at 22:53 Comment(1)
Where does control come from? You should at least provide where the control variable is defined or imported from what moduleFlaxseed
A
8

If anyone is getting any error while using hooks inside tests, try renderHook from testing-library/react:

import { render, renderHook } from '@testing-library/react'        

const { result } = renderHook(() => useForm())

render(
  <TextField control={result.current.control} />
)

Autarch answered 23/10, 2022 at 16:36 Comment(1)
I also used the above suggestion to build a mock control that I can pass into my component in Storybook like so: SORRY FOR THE NO FORMATTING import { renderHook } from "@testing-library/react" import { useForm } from "react-hook-form" const { result } = renderHook(() => useForm()) const mockControl = result.current.control export default mockControlKhmer
L
1

Maybe just passing in the real control from useForm, like they are doing in react-hook-form's testing. https://github.com/react-hook-form/react-hook-form/blob/master/src/__tests__/useController.test.tsx

Loiret answered 15/6, 2022 at 2:5 Comment(0)
M
0

control came from useForm:

const { control } = useForm();

Control is necessary when you use Controller or useController The doc: https://react-hook-form.com/api/usecontroller

I suppose the TaskModal component is in a form. I recommend to put the form inside the modal and it would be easier to test otherwise you can wrap your component (TaskModal) with a form for your test.

Mekong answered 22/12, 2021 at 8:7 Comment(2)
here is the whole code for the modal: pastebin.com/khvn3Vq5, here is the test: pastebin.com/JFfJkNRT, I've added the changes suggested by you but it still fails, returning this error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer(such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app reactjs.org/link/invalid-hook-callDextrorse
Please, read the documentation to know how to write test with react-hook-form: react-hook-form.com/advanced-usage#TestingFormMekong

© 2022 - 2024 — McMap. All rights reserved.