如何在jest react native上调用或模拟useForm?

2w3rbyxf  于 2023-03-11  发布在  Jest
关注(0)|答案(2)|浏览(208)

我有一个可重用的组件,称为DatePicker,如下所示

export interface IPDatePicker extends IProps {
  control: any
  label: string
  placeholder: string
  value?: string
  errorText?: string
  isRequired?: boolean
  name: string
  defaultValue?: any
  onChangeText: (value: string) => void
  minimumDate?: any
  maximumDate?: any
  timeOnly?: boolean
  hideLabel?: boolean
  labelMaxLine?: number
  //   setDateValue: any
}

const DatePicker: React.FC<IPDatePicker> = props => {
  const todaysDate = new Date()
  const [date, setDate] = useState<Date>(todaysDate)
  const [isDatePickerOpen, setIsDatePickerOpen] = useState(false)
  return (
    <Controller
      name={props?.name}
      defaultValue={props?.defaultValue}
      control={props?.control}
      render={({field: {onChange, value}}: any) => {.....}
    />

关键是,组件需要“控制”作为强制参数。
“控件”来自使用useForm的父页面/组件

const ParentPage = () => {
  const {
    control,
    formState: {errors, isValid, isDirty},
  } = useForm({
    resolver,
    mode: 'onChange',
    defaultValues: {
      date: '',
    },
  })
}

return (
   ...
   <DatePicker 
      control={control}  <-here
      name='date'
      ...
    />

)

我尝试创建一个测试文件,但我不知道如何在jest上调用useForm。它总是显示无效的钩子调用。钩子只能在函数组件的主体内调用

import React from 'react'
import {render, fireEvent} from '@testing-library/react-native'
import {IProps} from '@app/presentations/types'
import {DatePicker} from '@app/presentations/_shared-components'
import {useForm} from 'react-hook-form'

interface IPDatePicker extends IProps {
  control: any
  label: string
  placeholder: string
  value?: string
  errorText?: string
  isRequired?: boolean
  name: string
  defaultValue?: any
  onChangeText: (value: string) => void
}

function renderComponent(props: IPDatePicker) {
  const component = render(<DatePicker {...props} />)
  return {
    component,
    ...component,
  }
}

describe('DatePicker component', () => {
  it('Should render correctly', () => {
    const {control} = useForm({
      mode: 'onChange',
      defaultValues: {
        date: '',
      },
    })
    const component = renderComponent({
      control: control,
      label: 'Date picker',
      placeholder: 'Placeholder',
      onChangeText: v => {},
      name: 'date',
    })
    expect(component).toMatchSnapshot()
  })
})

这是错误图片

我的问题与此相似

34gzjxbg

34gzjxbg1#

最后我用这段代码修复了这个问题

jest.mock('react-hook-form', () => ({
  ...jest.requireActual('react-hook-form'),
  Controller: () => <></>,
  useForm: () => ({
    control: () => ({}),
    handleSubmit: () => jest.fn(),
  }),
}))
kq0g1dla

kq0g1dla2#

我设法用useForm测试类似的东西而不嘲笑它的方法是创建一个包含我想要测试的组件的组件。
示例:假设您要测试DatePicker组件,那么为了使用useForm中的control函数,我将执行以下操作:

// spec/javascript/DatePicker.spec.tsx file

import '@testing-library/jest-dom/extend-expect';
import { render } from '@testing-library/react';
import React from 'react';

const DatePickerWithForm = () => {
  const { control } = useForm();

  return <DatePicker control={control} ...some_other_attributes_here... />;
}

describe('DatePicker', () => {
  it('shows something', () => {
    const { getByText } = render(<DatePickerWithForm />);
    expect(getByText('Something')).toBeInTheDocument();
  });
});

完成此操作后,控制台中不再抛出钩子错误

相关问题