#material-ui #mocha.js #enzyme
Вопрос:
Это простой пример, который показывает проблему. (переход на поверхностное тестирование не подходит для реальных тестов). Этого не произошло в 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@muimaterialnodetransitionsutils.js:9:29)
at $SOMEPATHnode_modules@muimaterialnodeFadeFade.js:94:24
at Object.onEnter (node_modules@muimaterialnodeFadeFade.js:87:9)
at Transition.performEnter (node_modules@muimaterialnode_modulesreact-transition-groupcjsTransition.js:283:16)
at Transition.updateStatus (node_modules@muimaterialnode_modulesreact-transition-groupcjsTransition.js:249:14)
at Transition.componentDidMount (node_modules@muimaterialnode_modulesreact-transition-groupcjsTransition.js:193:10)
at commitLifeCycles (node_modulesreact-domcjsreact-dom.development.js:20663:24)
at commitLayoutEffects (node_modulesreact-domcjsreact-dom.development.js:23426:7)
at Object.invokeGuardedCallbackProd (node_modulesreact-domcjsreact-dom.development.js:3862:10)
at invokeGuardedCallback (node_modulesreact-domcjsreact-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 говорится:
«Вам нужно убедиться, что дочерние элементы пересылают ссылку в DOM для пользовательского компонента».
Вот что я пробовал
let r = React.createRef();
enzyme.mount(<Drawer
ref={r}
open={true}
>
<div>hello world</div>
</Drawer>);
Но это не имеет никакого значения, и в примерах документации Drawer
не передается ссылка.
Как я могу смонтировать тест 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@muimaterialnodetransitionsutils.js:9:29)
at $SOMEPATHnode_modules@muimaterialnodeFadeFade.js:94:24
at Object.onEnter (node_modules@muimaterialnodeFadeFade.js:87:9)
at Transition.performEnter (node_modules@muimaterialnode_modulesreact-transition-groupcjsTransition.js:283:16)
at Transition.updateStatus (node_modules@muimaterialnode_modulesreact-transition-groupcjsTransition.js:249:14)
at Transition.componentDidMount (node_modules@muimaterialnode_modulesreact-transition-groupcjsTransition.js:193:10)
at commitLifeCycles (node_modulesreact-domcjsreact-dom.development.js:20663:24)
at commitLayoutEffects (node_modulesreact-domcjsreact-dom.development.js:23426:7)
at Object.invokeGuardedCallbackProd (node_modulesreact-domcjsreact-dom.development.js:3862:10)
at invokeGuardedCallback (node_modulesreact-domcjsreact-dom.development.js:4056:31)
Однако тестирование внутреннего Fade
компонента работает без ошибок.
it('test Fade', () =>
{
const wrapper = enzyme.mount(<Fade in={true}><div>hello</div></Fade>);
console.log(wrapper.debug());
})
Ответ №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);
Затем вам просто нужно импортировать и использовать компоненты ModalPropsContext
in, которые используют Modal
компоненты.
Например:
<Dialog
{...this.context}
В производственном коде this.context равен {}, но в тестовом коде он возвращает disablePortal
hideBackdrop
и TransitionComponent
реквизит, необходимый для обходного пути.
Для получения дополнительной информации о том, как использовать контекст, см. Документы react context docs — (они отличаются для классов и функциональных компонентов.
Ответ №2:
Это помогло мне поместить содержимое, которое я хочу показать внутри Fade, в поле со 100vh
<Box minHeight="100vh">{children}</Box>