【问题标题】:Testing Material Ui (v5) Drawer - Cannot read property 'scrollTop' of null测试材料 Ui (v5) 抽屉 - 无法读取 null 的属性“scrollTop”
【发布时间】:2021-12-09 11:39:37
【问题描述】:

这是一个显示问题的简单示例。 (切换到浅层测试不是真正测试的选择)。这在materialui v4中没有发生。 (仅升级到 mui v5 后)

it('Test Drawer', () =>
{
    enzyme.mount(<Drawer  
        open={true}
    >
        <div>hello world</div>
    </Drawer>);        
})

产生以下错误:

TypeError: Cannot read property 'scrollTop' of null
    at reflow (node_modules\@mui\material\node\transitions\utils.js:9:29)
    at $SOMEPATH\node_modules\@mui\material\node\Fade\Fade.js:94:24
    at Object.onEnter (node_modules\@mui\material\node\Fade\Fade.js:87:9)
    at Transition.performEnter (node_modules\@mui\material\node_modules\react-transition-group\cjs\Transition.js:283:16)
    at Transition.updateStatus (node_modules\@mui\material\node_modules\react-transition-group\cjs\Transition.js:249:14)
    at Transition.componentDidMount (node_modules\@mui\material\node_modules\react-transition-group\cjs\Transition.js:193:10)
    at commitLifeCycles (node_modules\react-dom\cjs\react-dom.development.js:20663:24)
    at commitLayoutEffects (node_modules\react-dom\cjs\react-dom.development.js:23426:7)
    at Object.invokeGuardedCallbackProd (node_modules\react-dom\cjs\react-dom.development.js:3862:10)
    at invokeGuardedCallback (node_modules\react-dom\cjs\react-dom.development.js:4056:31)

lib 版本

"react": "^17.0.2",
"@mui/material": "^5.0.4",
"enzyme": "^3.9.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.3",

现在是 v4 -> v5 迁移指南 says:

“您需要确保子组件将 ref 转发到 DOM 以获取自定义组件。”

这是我尝试过的

        let r = React.createRef();

        enzyme.mount(<Drawer
            ref={r}
            open={true}
        >
            <div>hello world</div>
        </Drawer>);

但这没有什么区别,Drawerdocumentation 示例没有通过引用。

如何挂载测试Drawer?这只发生在测试中(不是在实际运行时)

更新:

测试安装Modal 做同样的事情:

it('test Modal', () =>
{
    const wrapper = enzyme.mount(<Modal open={true}><div>hello</div></Modal>);

    console.log(wrapper.debug());
})

因此产生此错误:

TypeError: Cannot read property 'scrollTop' of null
at reflow (node_modules\@mui\material\node\transitions\utils.js:9:29)
at $SOMEPATH\node_modules\@mui\material\node\Fade\Fade.js:94:24
at Object.onEnter (node_modules\@mui\material\node\Fade\Fade.js:87:9)
at Transition.performEnter (node_modules\@mui\material\node_modules\react-transition-group\cjs\Transition.js:283:16)
at Transition.updateStatus (node_modules\@mui\material\node_modules\react-transition-group\cjs\Transition.js:249:14)
at Transition.componentDidMount (node_modules\@mui\material\node_modules\react-transition-group\cjs\Transition.js:193:10)
at commitLifeCycles (node_modules\react-dom\cjs\react-dom.development.js:20663:24)
at commitLayoutEffects (node_modules\react-dom\cjs\react-dom.development.js:23426:7)
at Object.invokeGuardedCallbackProd (node_modules\react-dom\cjs\react-dom.development.js:3862:10)
at invokeGuardedCallback (node_modules\react-dom\cjs\react-dom.development.js:4056:31)

但是测试内部 Fade 组件可以正常工作。

it('test Fade', () =>
{
    const wrapper = enzyme.mount(<Fade in={true}><div>hello</div></Fade>);

    console.log(wrapper.debug());
})

【问题讨论】:

    标签: material-ui mocha.js enzyme


    【解决方案1】:

    解决方法 - 在Drawer 或任何基于Modal 的组件(例如Dialog)上应用以下道具以在运行测试时禁用转换。

    const disableTransitionProps = {
            disablePortal: true,
            hideBackdrop: true,
            TransitionComponent: ({ children }) => children
          };
    
    
    enzyme.mount(<Drawer          
            open={true}
            {...disableTransitionProps }
        >
            <div>hello world</div>
        </Drawer>);
    

    更新

    我在反应上下文中总结了解决方法

    // ModalProps.Context.jsx
    import React from 'react';
    
    const ModalPropsContext = React.createContext({});
    
    // for unittest - workaround MUI c5 (5.0.5) Transitions bugs when runing tests.
    export const DefaultForTests = {value : {
                    disablePortal : true,
                    hideBackdrop: true,
                    TransitionComponent: ({ children }) => children
                }}
    
    // For unittests            
    export const MountRendererPropsForModalComponents = {wrappingComponent : ModalPropsContext.Provider, wrappingComponentProps : DefaultForTests};
    
    export default ModalPropsContext;
    

    可以这样使用:

    import {MountRendererPropsForModalComponents} from 'ModalPropsContext.jsx'
    

    然后:

    const wrapper = enzyme.mount(<SomeComponentThatContainsModalComponents />, MountRendererPropsForModalComponents);
    

    那么你只需要在使用Modal组件的组件中导入并使用ModalPropsContext即可。

    例如:

    <Dialog 
       {...this.context}
    

    在生产代码中 this.context 是 {},但在测试代码中它返回解决方法所需的 disablePortalhideBackdropTransitionComponent 道具。

    有关如何使用上下文的更多信息,请参阅react context docs -(对于类和功能组件而言,它有所不同。

    【讨论】:

      猜你喜欢
      • 2022-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 2019-06-01
      • 2019-08-09
      • 2020-11-16
      • 2015-05-14
      相关资源
      最近更新 更多