Неспособность имитировать компонент реакции ребенка в тестах

#reactjs #unit-testing #jestjs #react-testing-library

Вопрос:

Об этом есть куча статей и примеров, но по какой-то причине, похоже, ничего не работает.

У меня есть компонент react, у которого есть дочерний компонент. И, для простоты, я хочу высмеять дочерний компонент в тесте.

Компонент выглядит следующим образом:

 ...
import { ProjectTeam } from '../../assignment/project-team/component';

export const ProjectOverview: React.FC<ProjectOverviewProps> = ({ projectId }) => {
  ...

  return (
    <>
      ...
        <Box flex={1}>
          <ProjectTeam projectId={projectId} />
        </Box>
        ...
    </>
  );
};
 

Компонент ProjectTeam:

 export const ProjectTeam: React.FC<ProjectTeamProps> = ({ projectId }) => {
  // just a standard component... 
};
 

А вот и тест:

 import React from 'react';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
import { render } from '@testing-library/react';
import { I18nextProvider } from 'react-i18next';
import { generateProject } from '../../testing/generators/project';
import { ProjectOverview } from './component';
import { NGStateProvider } from '../../react/providers/route-provider/component';
import { testAngularRouter } from '../../testing/testAngularRouter';
import { DefaultProjectCollection, DefaultUtilizationCollection } from '../store/model';
import { DefaultApaActionCollection } from '../../apa/model';
import i18n from '../../testing/i18n';
import thunk from 'redux-thunk';

describe('ProjectOverview', () => {
  let mockStore = null;
  const project = generateProject();

  beforeEach(() => {
    jest.mock('../../assignment/project-team/component', () => ({ ProjectTeam: 'ProjectTeam' }));

    mockStore = configureMockStore([thunk])({
      projects: { DefaultProjectCollection, ...{ entities: { [project.id]: project } } },
      toolUtilizations: DefaultUtilizationCollection,
      apaActions: DefaultApaActionCollection,
    });
  });

  test('renders correctly', () => {
    const { asFragment } = render(
      <NGStateProvider router={testAngularRouter}>
        <Provider store={mockStore}>
          <I18nextProvider i18n={i18n}>
            <ProjectOverview projectId={project.id} />
          </I18nextProvider>
        </Provider>
      </NGStateProvider>,
    );
    expect(asFragment()).toMatchSnapshot();
  });
});
 

Мое предположение, что jest.mock(...) следует просто заменить дочерний компонент в тестовом режиме. Однако это не так. Весь компонент пытается отобразить как есть.

Вот одна из статей, на которую я ссылался: https://thoughtbot.com/blog/mocking-react-components-with-jest

Ответ №1:

Попробуйте перенести jest.mock звонок на улицу. Я бы сказал, прямо наверху, непосредственно перед describe разделом и за его пределами.

Jest должен знать о насмешливом компоненте, прежде чем он начнет выполнять соответствующий тестовый файл.

В статье, на которую вы ссылаетесь, есть эта информация,

введите описание изображения здесь

Кроме того, вы можете поместить его в __mocks__ папку рядом с компонентом, если это ваше предпочтение.

Комментарии:

1. @Шурикагулянский Да, такое иногда случается. Мы склонны упускать эти детали. Рад, что у тебя все получилось хорошо.