#reactjs #jestjs #formik
Вопрос:
Я проводил интеграционные тесты интерфейсных страниц моего проекта с помощью библиотеки jest и react-тестирования и столкнулся с ошибкой, которую я не до конца понимаю.
Страница, которую я тестирую, отображает форму, в которой пользователи вводят данные для коммерческого учреждения:
import React from 'react';
import {
FormGroup, Label, Row,
} from 'reactstrap';
import {
Field, getIn, FieldArray, useFormikContext,
} from 'formik';
import { useRecoilValue } from 'recoil';
import Select from 'react-select';
import {
institutionTypeAtom,
} from 'recoil/institution';
import { Colxx } from 'components/common/CustomBootstrap';
import IntlMessages from 'helpers/IntlMessages';
import { FormikStep } from 'components/Stepper/Step';
const InstitutionStep1 = ({ label, isView, validationSchema }) => {
const {
values, errors, touched, setFieldValue,
} = useFormikContext();
const types = useRecoilValue(institutionTypeAtom);
const typeFind = (values) => {
types.find((t) => t.institution_type_id === values.institution_type_id);
return values.institution_type_id;
};
return (
<FormikStep>
<Colxx xxs="4">
<FormGroup>
<Label>
<IntlMessages id="institution.type" />
</Label>
<Select
placeholder="Selecione o tipo"
value={types.find((t) => t.institution_type_id === values.institution_type_id)}
isDisabled={isView}
onChange={(selectedType) => {
setFieldValue('institution_type_id', selectedType.institution_type_id);
}}
options={types}
className="react-select"
classNamePrefix="react-select"
name="institution_type_id"
aria-label="institution_type_id"
getOptionLabel={(option) => option.institution_type}
getOptionValue={(option) => option.institution_type_id}
/>
{getIn(errors, 'institution_type_id') amp;amp; getIn(touched, 'institution_type_id') amp;amp; (
<div className="invalid-feedback d-block">
{getIn(errors, 'institution_type_id')}
</div>
)}
</FormGroup>
</Colxx>
</Row>
</FormikStep>
);
};
export default InstitutionStep1;
и одно из полей ввода-это выбор, в котором он может выбрать тип учреждения (частное, государственное, иностранное…). Я также использую шаг, и formikStep-это конечный компонент из этого шага, который получает начальные значения:
export const institutionInitialValues: InitialValues<BaseInstitutionType> = (institution = {}) => ({
institution_type_id: institution.institution_type_id ? institution.institution_type_id : '',
deleted: !!institution.deleted,
});
И я написал свой тест, чтобы пользователи могли выбирать на отображаемой странице, но я также очень новичок в области тестирования, поэтому я ссылаюсь на другие тесты, которые уже были в этом проекте:
import React from 'react';
import userEvent from '@testing-library/user-event';
import {
cleanup, screen, act, render, waitFor, renderWithRecoilSnapshot,
} from 'testWrapper';
import * as institution from 'services/adminModules/institution';
import {
generateMockInstitution, mockAxiosResponse,
} from 'helpers/testMocks';
import { institutionTypeAtom } from 'recoil/institution';
import InstitutionForm from '../../views/app/admin/InstitutionsPage/InstitutionForm';
let createInstitution: jest.SpyInstance;
const mockInstitution = generateMockInstitution();
const mockSubmit = jest.fn();
const mockClose = jest.fn();
const renderComponent = () => renderWithRecoilSnapshot(<InstitutionForm
handleClose={mockClose}
handleSubmit={mockSubmit}
/>,
({ set }) => {
set(institutionTypeAtom, 1);
});
describe('InstitutionFormPage', () => {
afterEach(cleanup);
beforeEach(() => {
createInstitution = jest.spyOn(institution, 'createInstitution').mockImplementation(async () => mockAxiosResponse());
jest.spyOn(institution, 'getInstitution').mockImplementation(async () => mockAxiosResponse());
});
it('should submit institution data', async () => {
renderComponent();
await waitFor(() => expect(screen.queryByText('loading')).not.toBeInTheDocument());
screen.logTestingPlaygroundURL();
const institution_type_id = screen.getByRole('select', { name: 'institution_type_id' });
expect(institution_type_id).toBeInTheDocument();
await act(async () => {
await userEvent.selectOptions(institution_type_id, mockInstitution.institution_type_id);
});
const button = screen.getByRole('button', { name: /salvar/i });
expect(button).toBeInTheDocument();
await act(async () => {
await userEvent.click(button);
});
await waitFor(() => expect(mockSubmit).toHaveBeenCalledWith(mockInstitution));
});
});
По-видимому, тест верен, но при запуске я получаю ошибку, в которой говорится, что a .находка, которую я использую в компоненте, не является функцией.
Поэтому мой главный вопрос будет заключаться в следующем: означает ли это, что тест верен и правильно улавливает ошибку кода? Или это неправильно, и это не может продолжаться? Кроме того, код, на который он жалуется, работает нормально, и меня учили, что интеграционный тест проверяет запросы api, так есть ли причина, по которой тест будет жаловаться на это, но код будет работать нормально?
Комментарии:
1. Можете ли вы выполнить console.log(типы) внутри своего компонента и снова запустить тест . Похоже, что типы — это не
Array
2. Ты прав. Журнал консоли показывает, что типы-это массив, когда я запускаю проект, получаю доступ к компоненту и использую его, но когда я запускаю тест, журнал консоли выводит только число 1. Я предполагаю, что это означает, что макет выбора неверен, тогда