Перемешивание React.Suspense, оставляя остальную часть React без изменений - PullRequest
0 голосов
/ 02 января 2019

Я пытаюсь написать Jest модульный тест для компонента, который использует React.Suspense .

Упрощенные версии тестируемых моих компонентных модулей:

MyComponent.js

import React from 'react';

export default () => <h1>Tadaa!!!</h1>;

MySuspendedComponent.js

import React, { Suspense } from 'react';
import MyComponent from './MyComponent';

export default () => (
    <Suspense fallback={<div>Loading…</div>}>
        <MyComponent />
    </Suspense>
);

Наивно, в моей первой попытке, я написал модульный тест, в котором для установки приостановленного компонента используется Фермент :

MySuspendedComponent.test.js

import React from 'react';
import { mount } from 'enzyme';
import MySuspendedComponent from './MySuspendedComponent';

test('the suspended component renders correctly', () => {
    const wrapper = mount(<MySuspendedComponent />);
    expect(wrapper.html()).toMatchSnapshot();
});

Это приводит к сбою теста с сообщением об ошибке:

Ошибка: внутренняя ошибка фермента: неизвестный узел с тегом 13

При поиске сообщения об ошибке в Интернете я обнаружил, что это, скорее всего, вызвано тем, что Enzyme еще не готов к визуализации Suspense (пока).

Если я использую shallow вместо mount, сообщение об ошибке изменится на:

Инвариантное нарушение: ReactDOMServer еще не поддерживает Suspense

Моя следующая попытка состояла в том, чтобы смоделировать Suspense с помощью фиктивного сквозного компонента, например:

MySuspendedComponent.test.js

import React from 'react';
import { mount } from 'enzyme';
import MySuspendedComponent from './MySuspendedComponent';

jest.mock('react', () => {
    const react = require.requireActual('react');
    return () => ({
        ...react,
        Suspense({ children }) {
            return children;
        }
    });
});

test('the suspended component renders correctly', () => {
    const wrapper = mount(<MySuspendedComponent />);
    expect(wrapper.html()).toMatchSnapshot();
});

Идея состоит в том, чтобы иметь фиктивную реализацию модуля React, содержащего весь фактический код из библиотеки React, с заменой только Suspense на фиктивную функцию.

Я использовал этот шаблон с requireActual, как описано в документации Jest , успешно в других модульных тестах при моделировании других модулей, кроме React, но с React он не работает.

Ошибка, которую я получаю сейчас:

TypeError: (($ _ $ w (...), реагировать) || ($ $ w (...), _load_react (...))). Default.createElement is не функция

… что, как я полагаю, вызвано тем, что первоначальная реализация React не была доступна после моего трюка с насмешками.

Как я могу сделать макет Suspense, оставив остальную часть библиотеки React нетронутой?

Или есть другой, лучший способ проверить подвесные компоненты?

1 Ответ

0 голосов
/ 02 января 2019

Решение состоит не в том, чтобы использовать расширение объекта для экспорта исходного модуля React, а просто в перезаписи свойства Suspense, например:

MySuspendedComponent.test.js

import React from 'react';
import { mount } from 'enzyme';
import MySuspendedComponent from './MySuspendedComponent';

jest.mock('react', () => {
    const React = jest.requireActual('react');
    React.Suspense = ({ children }) => children;
    return React;
});

test('the suspended component renders correctly', () => {
    const wrapper = mount(<MySuspendedComponent />);
    expect(wrapper.html()).toMatchSnapshot();
});

Это создает следующий снимок, как и ожидалось:

MySuspendedComponent.test.js.snap

exports[`the suspended component renders correctly 1`] = `"<h1>Tadaa!!!</h1>"`;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...