【问题标题】:Jest + React Testing Library: Portals are not being cleaned upJest + React 测试库:门户没有被清理
【发布时间】:2021-04-28 10:51:04
【问题描述】:

据我了解,React 测试库会在每次测试后自动清理您的 DOM(至少在您使用 Jest 时)。

这适用于在我的 root 节点内呈现的任何内容,但在 root 之外使用 Portals 呈现的任何内容都不会被清理并在测试中保持不变。

不幸的是,我的一些组件依赖于使用门户呈现的modal 组件,因此一旦打开此组件,我就无法在后续测试中将其从 DOM 中删除。

我该如何解决这个问题?

【问题讨论】:

    标签: reactjs jestjs react-testing-library


    【解决方案1】:

    我与ant-design 有完全相同的问题,我找到了 2 个解决方案。

    解决方案 #1,在调用 render 时添加一个附加选项 container: document.body(适用于警告,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,在 afterEach 中使用 removeChild 手动删除模式

    afterEach(() => {
        const modals = document.querySelectorAll('.ant-modal-wrap');
        modals.forEach((modal) => modal.parentNode.removeChild(modal));
    });
    
    test('blah blah', () => {
        render(<CreateOrEditAvailability isEdit={false} />, { initialState });
        ...
    });
    

    【讨论】:

    • 我可以通过 screen.debug() 从 DOM 中删除 Modal,但它似乎破坏了后续测试,无法创建未来的 Modal。我使用 Microsoft Fluent-UI,而不是 ant-design。仍然找不到适用于一般情况的另一种解决方案。
    • @kelvien 不同的UI框架有不同的Modal组件实现,尤其是Modal的挂载位置(document.body或其他地方),没有通用的解决方案b/c UI框架不遵循通用标准用于模态组件。
    猜你喜欢
    • 2021-09-15
    • 2021-05-26
    • 2019-11-27
    • 2023-02-17
    • 2018-06-14
    • 2020-03-24
    • 2023-02-04
    • 2020-04-21
    • 2019-10-08
    相关资源
    最近更新 更多