使用Jest和react测试库测试具有大量输入字段的表单的正确方法是什么



我有一个有很多输入的表单,问题是,有没有一种方法可以简化对所有这些单个输入变量的处理,因为它们的列表看起来很难看。对一个有两个输入的表单的测试看起来既干净又优雅,但这次看起来我做错了什么。还有一个"specialized"数据变量,我认为它不属于mocks文件夹,因为它不是一个模拟的api调用,只是表单的一个道具。有没有一个约定,我应该把这些变量放在测试文件夹的哪里?如果有其他关于我做错了什么的反馈,我将不胜感激,谢谢。

import React from 'react'
import { Provider } from 'react-redux'
import { render, screen } from '@testing-library/react'
import store from '../../../store'
import PupilForm from '../../../components/forms/PupilForm'
import specialties from '../../../__mocks__/specialties.json'
const mockHandleFormData = jest.fn()
const mockOpenInfoModal = jest.fn()
describe('<PupilForm /> component', () => {
// eslint-disable-next-line
let view
// inputs
let nameInput
let specialtyInput
let genderInput
let birthDateInput
let mainSchoolClassInput
let benefitsInput
let mainSchoolInput
let homeAddressInput
let phoneNumberInput
let applicantNameInput
let contactEmailInput
let fathersNameInput
let fathersPhoneInput
let fathersEmploymentInfoInput
let mothersNameInput
let mothersPhoneInput
let mothersEmploymentInfoInput
// checkboxes
let docsCheck
let processDataCheck
let paymentObligationsCheck
// buttons
let submitButton
let resetButton

beforeEach(() => {
view = render(
<Provider store={store}>
<PupilForm
handleFormData={mockHandleFormData}
openInfoModal={mockOpenInfoModal}
specialties={specialties.map(spec => spec.title)}
mode="public"
/>
</Provider>
)
nameInput = screen.getByRole('textbox', { name: /Прізвище та повне ім'я учня/ })
specialtyInput = screen.getByRole('combobox', { name: /Фах/ })
genderInput = screen.getByRole('combobox', { name: /Стать/ })
birthDateInput = screen.getByLabelText(/Дата народження/)
mainSchoolClassInput = screen.getByRole('combobox', { name: /Клас ЗОШ/ })
benefitsInput = screen.getByRole('combobox', { name: /Пільги %/ })
mainSchoolInput = screen.getByRole('textbox', { name: /В якому закладі навчается/ })
homeAddressInput = screen.getByRole('textbox', { name: /Домашня адреса/ })
phoneNumberInput = screen.getByRole('textbox', { name: /Телефонний номер учня/ })
applicantNameInput = screen.getByRole('textbox', { name: /Ім'я особи, яка звертається із заявою/ })
contactEmailInput = screen.getByRole('textbox', { name: /Контактна електронна пошта/ })
fathersNameInput = screen.getByRole('textbox', { name: /Ім'я батька/ })
fathersPhoneInput = screen.getByRole('textbox', { name: /Телефонний номер батька/ })
fathersEmploymentInfoInput = screen.getByRole('textbox', { name: /Місце роботи батька/ })
mothersNameInput = screen.getByRole('textbox', { name: /Ім'я матері/ })
mothersPhoneInput = screen.getByRole('textbox', { name: /Телефонний номер матері/ })
mothersEmploymentInfoInput = screen.getByRole('textbox', { name: /Місце роботи матері/ })
docsCheck = screen.getByRole('checkbox', { name: /Я зобов'язаний надати ці документи/ })
processDataCheck = screen.getByRole('checkbox', { name: /Я згоден на збір та обробку/ })
paymentObligationsCheck = screen.getByRole('checkbox', { name: /Зобов'язання про оплату/ })
submitButton = screen.getByRole('button', { name: /Відправити/ })
resetButton = screen.getByRole('button', { name: /Очистити/ })
})
it('in renders all fields correctly', () => {
expect(/Дані/інформація про учня/).toBeInTheDocument
expect(nameInput).toHaveAttribute('type', 'text')
expect(specialtyInput).toHaveClass('custom-select')
expect(genderInput).toHaveClass('custom-select')
expect(birthDateInput).toHaveAttribute('type', 'date')
expect(mainSchoolClassInput).toHaveClass('custom-select')
expect(benefitsInput).toHaveClass('custom-select')
expect(mainSchoolInput).toHaveAttribute('type', 'text')
expect(homeAddressInput).toHaveAttribute('type', 'text')
expect(phoneNumberInput).toHaveAttribute('type', 'text')
expect(applicantNameInput).toHaveAttribute('type', 'text')
expect(contactEmailInput).toHaveAttribute('type', 'email')
expect(/Дані/інформація о батьках/).toBeInTheDocument
expect(fathersNameInput).toHaveAttribute('type', 'text')
expect(fathersPhoneInput).toHaveAttribute('type', 'text')
expect(fathersEmploymentInfoInput).toHaveAttribute('type', 'text')
expect(mothersNameInput).toHaveAttribute('type', 'text')
expect(mothersPhoneInput).toHaveAttribute('type', 'text')
expect(mothersEmploymentInfoInput).toHaveAttribute('type', 'text')
expect(docsCheck).toHaveAttribute('type', 'checkbox')
expect(processDataCheck).toHaveAttribute('type', 'checkbox')
expect(paymentObligationsCheck).toHaveAttribute('type', 'checkbox')
expect(submitButton).toHaveAttribute('type', 'submit')
expect(resetButton).toHaveAttribute('type', 'reset')
})
/*
it('some other test that uses the same inputs', () => {
// expect all inputs to be able to change their values on user input
})
*/
})

有没有一种方法可以简化对所有这些单个输入变量的处理?

我不这么认为。我个人会去掉所有字段变量,只通过screen访问它们。但做你觉得合适的事。

您也可以尝试缩短一些查询。由于您使用的是regex,因此不需要指定整个元素name


但这一次看起来我做错了

测试看起来不错。我想指出的是,你可能不需要测试某些东西,比如expect(nameInput).toHaveAttribute('type', 'text'),因为你已经用nameInput = screen.getByRole('textbox', { name: /Прізвище та повне ім'я учня/ })免费获得了大部分。

你也会在上面使用类似userEvent.type的东西,所以,我认为它已经足够安全了。


还有一个"specialized"数据变量,我认为它不属于mocks文件夹,因为它不是一个模拟的api调用,只是形式的道具

mocks文件夹下保存测试数据时,我也没有发现任何问题,即使它不是在嘲笑API调用。

如果您认为在语义上更合适,也许您可以将文件夹命名为fixtures。或者你可以把它保存在将使用它的测试文件中。这似乎是一种代码风格的偏好,每个人都会对它有不同的看法。


是否有将此类变量放入测试文件夹的约定?

__mocks__fixturesdata,你能想到的。我建议你四处移动,直到感觉合适,然后咨询团队成员。

这个问题与非常相似

最新更新