繁体   English   中英

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

[英]What is the proper way to test a form with a lot of input fields using Jest and react-testing-library?

我有这个包含很多输入的表单,问题是,有没有办法简化所有这些单个输入变量的处理,因为它们的列表看起来非常难看。 具有两个输入的表单的测试看起来干净而优雅,但这个看起来好像我做错了什么。 还有一个“专业”数据变量,我认为它不属于 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访问它们。 但做你觉得合适的事。

您也可以尝试缩短一些查询。 由于您使用的是正则表达式,因此无需指定整个元素name


但这个看起来我做错了什么

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

您还将在其上使用诸如userEvent.type东西,因此我认为它已经足够安全了。


还有一个“专业”数据变量,我认为它不属于 mocks 文件夹,因为它不是模拟的 api 调用,只是表单的一个道具

我也没有看到在mocks文件夹下有测试数据的任何问题,即使它不是模拟 API 调用。

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


是否有关于将这些变量放在测试文件夹中的位置的约定?

__mocks__fixturesdata ,你说出来的。 我建议你移动它直到感觉合适,然后咨询团队成员。

这个问题非常相似

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM