Jest/React-testing-библиотека: .find не является функцией в тестируемом компоненте

#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. Я предполагаю, что это означает, что макет выбора неверен, тогда