Как заменить компонент React на макет при тестировании с помощью Jest - PullRequest
2 голосов
/ 18 июня 2020

Я действительно застрял на этом в проекте, над которым я работаю, и все ответы, которые я нашел, кажутся такими простыми, но они не сработали для меня. Возможно, я действительно не понимаю, что такое макет, и мне действительно пригодились бы некоторые рекомендации.

Я тестирую родительский компонент, у которого есть дочерний компонент, который извлекает некоторые данные из базы данных с помощью GraphQL. Во время тестирования родителя мне все равно, что делает ребенок. Я хочу заменить дочерний компонент на фиктивный компонент (тот, который не извлекает данные из базы данных), чтобы я мог сосредоточиться только на родительском элементе.

Я придумал самый простой пример ситуация. Обратите внимание, что я использую React Native и React Native Testing Library.

. / Src / ParentComponent. js

import React from 'react';
import { Text, View } from 'react-native';
import ChildComponent from './ChildComponent';

const ParentComponent = () => (
  <View>
    <Text>Hello World</Text>
    <ChildComponent />
  </View>
);

export default ParentComponent;

. / Src /ChildComponent.js

import React from 'react';
import { useQuery } from 'react-apollo';
import { View, Text } from 'react-native';
import gql from 'graphql-tag';

const CURRENT_USER_QUERY = gql`
  query {
    currentUser {
      username
    }
  }
`;

const ChildComponent = () => {
  const { data } = useQuery(CURRENT_USER_QUERY);
  const { username } = data.currentUser;

  return (
    <View>
      <Text>Welcome, {username}</Text>
    </View>
  );
};

export default ChildComponent;

. / Src / __ издевается над __ / ChildComponent. js

import React from 'react';
import { Text } from 'react-native';

const ChildComponent = () => <Text>Welcome.</Text>;

export default ChildComponent;

. / Src /ParentComponent.test.js

import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import { render } from '@testing-library/react-native';
import ParentComponent from '../ParentComponent';

it(`should render the parent component.`, () => {
  jest.mock('../ChildComponent');
  const { getByText } = render(
    <MockedProvider>
      <ParentComponent />
    </MockedProvider>
  );

  expect(getByText('Hello World')).toBeTruthy();
});

Когда я запускаю тест, я получаю следующую ошибку ...

  ● should render the parent component.

    TypeError: Cannot read property 'currentUser' of undefined

      14 | const ChildComponent = () => {
      15 |   const { data } = useQuery(CURRENT_USER_QUERY);
    > 16 |   const { username } = data.currentUser;
         |                             ^
      17 |
      18 |   return (
      19 |     <View>

      at ChildComponent (src/ChildComponent.js:16:29)

Он все еще использует реальный <ChildComponent />. Почему он не заменяет <ChildComponent /> фиктивной версией в каталоге __mocks__? Разве не так работают макеты? Если кто-то может помочь и объяснить, это было бы очень полезно. Спасибо.

1 Ответ

2 голосов
/ 19 июня 2020

После нескольких дней ломки мозга над этим, я наконец понял, в чем дело. Я вызывал макет внутри объявления it. Когда я переместил строку jest.mock('../ChildComponent'); наверх, все заработало. Итак, тестовый файл должен выглядеть так ...

import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import { render } from '@testing-library/react-native';
import ParentComponent from '../ParentComponent';

jest.mock('../ChildComponent');

it(`should render the parent component.`, () => {
  const { getByText } = render(
    <MockedProvider>
      <ParentComponent />
    </MockedProvider>
  );

  expect(getByText('Hello World')).toBeTruthy();
});
...