Как проверить внутреннюю функцию в функциональном компоненте контейнера - PullRequest
1 голос
/ 21 февраля 2020

Мне нужно перенести мое приложение из классов в функции. Во время рефакторинга я обнаружил две проблемы с модульными тестами.

  1. Как получить доступ к функции внутреннего компонента, которая отображает другой компонент React?
  2. Как смоделировать презентационный компонент внутри метода визуализации контейнера?

Рассмотрим два компонента:

ComponentToTest

import React from "react";
import PropTypes from "prop-types";

import {ViewToTest} from "./ViewToTest";

export function ComponentToTest(props) {
    const internalFunction = () => {
        return 'internal function'
    };

    React.useEffect(() => {
        internalFunction();
    }, []);

    return (
        <ViewToTest clientProductId={props.clientProductId} productShortName={props.productShortName}/>
    )
}

ComponentToTest.propTypes = {
    clientProductId: PropTypes.number.isRequired,
    DataProductGeolocations: PropTypes.shape({
        clientProductGeolocationCountries: PropTypes.arrayOf(PropTypes.object),
        loading: PropTypes.bool,
    }),
    productShortName: PropTypes.string.isRequired,
};
ComponentToTest.defaultProps = {
    DataProductGeolocations: {
        clientProductGeolocationCountries: [],
        loading: false,
    },
};

и ViewToTest

import React from "react";
import PropTypes from "prop-types";

export const ViewToTest = (props) => {
    return (
        <>
            <div>ViewToTest</div>
            <div>{props}</div>
        </>
    )
};

ViewToTest.propTypes = {
    clientProductId: PropTypes.number.isRequired,
    productShortName: PropTypes.string.isRequired,
};
ViewToTest.displayName = 'ViewToTest';

Я написал простой тест для ComponentToTest

import React from "react";

import {ComponentToTest} from "./ComponentToTest";

jest.mock('./ViewToTest', () => {
    return function MockedViewToTest(props) {
        return (
            <div>
                <div>clientProductId: {props.clientProductId}</div>
                <div>productShortName: {props.productShortName}</div>
            </div>
        )
    }
});

describe('A ComponentToTest suite', () => {
    test('should match snapshot', () => {
        const component = shallow(
            <ComponentToTest clientProductId={666} productShortName={'lco'} />
        );

        expect(component.debug()).toMatchSnapshot();
    });

    test('should call internalFunction() after first render', () => {
        const component = shallow(
            <ComponentToTest clientProductId={666} productShortName={'lco'} />
        );
        const instance = component.instance();

        expect(instance.internalFunction()).toHaveBeenCalled();
    });
});

Первый тест генерирует моментальный снимок:

<Component clientProductId={666} productShortName=\"lco\" />

И вопрос в том, как изменить имя макетируемого компонента с Компонент на * ViewToTest *?

Второй тест не пройден с предупреждением:

Предупреждение: React.createElement: тип недействителен - ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: undefined. Скорее всего, вы забыли экспортировать компонент из файла, в котором он определен, или вы перепутали импорт по умолчанию и имя.

и ошибка:

Ошибка ввода: Ошибка чтения свойство 'internalFunction' равно нулю

Если вы проверите, что такое компонент , отображаемый с shallow , вы увидите:

<Component clientProductId={666} productShortName="lco" />

вместо из ComponentToTest

Как мне написать тест, чтобы иметь правильное имя компонента в снимке и экземпляр ComponentToTest во втором тесте?

...