Библиотека тестирования Jest React: Порталы не очищаются

#reactjs #jestjs #react-testing-library

Вопрос:

Насколько я понимаю, библиотека тестирования React автоматически очищает ваш DOM после каждого теста (по крайней мере, когда вы используете Jest).

Это работает для всего, что отображается внутри моего root узла, но все, что было отображено снаружи root с помощью порталов, не очищается и сохраняется в тестах.

К сожалению, некоторые из моих компонентов зависят от modal компонента, который отображается с помощью портала, поэтому, как только этот компонент был открыт, у меня нет возможности удалить его из DOM в последующих тестах.

Как мне обойти эту проблему?

Ответ №1:

У меня точно такая же проблема ant-design , я нашел 2 решения.

Решение № 1, добавьте дополнительную опцию container: document.body при вызове render (работает с предупреждениями, НЕ поощряется testing-library )

 render(<CreateOrEditAvailability isEdit={false} />, { initialState, container: document.body });
 

Предупреждения:

  • № 1
 Warning: render(...): Replacing React-rendered children with a new root component. If you intended to update the children of this node, you should instead have the existing children update their state and render the new components instead of calling ReactDOM.render.

      at printWarning (node_modules/react-dom/cjs/react-dom.development.js:88:30)
      at error (node_modules/react-dom/cjs/react-dom.development.js:60:5)
      at topLevelUpdateWarnings (node_modules/react-dom/cjs/react-dom.development.js:24664:7)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:24733:5)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:24840:10)
      at node_modules/@testing-library/react/dist/pure.js:99:25
      at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:21856:12)
 
  • № 2
 Warning: render(): Rendering components directly into document.body is discouraged, since its children are often manipulated by third-party scripts and browser extensions. This may lead to subtle reconciliation issues. Try rendering into a container element created for your app.

      at printWarning (node_modules/react-dom/cjs/react-dom.development.js:88:30)
      at error (node_modules/react-dom/cjs/react-dom.development.js:60:5)
      at topLevelUpdateWarnings (node_modules/react-dom/cjs/react-dom.development.js:24668:7)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:24733:5)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:24840:10)
      at node_modules/@testing-library/react/dist/pure.js:99:25
      at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:21856:12)
 

Решение № 2, удалите модалы вручную с removeChild помощью in afterEach

 afterEach(() => {
    const modals = document.querySelectorAll('.ant-modal-wrap');
    modals.forEach((modal) => modal.parentNode.removeChild(modal));
});

test('blah blah', () => {
    render(<CreateOrEditAvailability isEdit={false} />, { initialState });
    ...
});
 

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

1. Я могу удалить Модальный из DOM , выполнив screen.debug() это, но, похоже, это мешает последующим тестам создавать будущий модальный. И я использую Microsoft Fluent-UI, а не ant-дизайн. Все еще не мог найти другого решения, которое работает для общих случаев.

2. @kelvien Разные фреймворки пользовательского интерфейса имеют разные реализации модальных компонентов, особенно в том, где монтировать модалы (документ. тело или где-то еще), нет общего решения, в рамках пользовательского интерфейса b/c не соблюдается общий стандарт для модального компонента.