我已经为模态窗口编写了一个组件,把它放在createPortal中。我想为此编写一个测试,但出现错误: console.error 错误:未捕获 [错误:目标容器不是 DOM 元素。 由于某些原因,测试没有看到我的组件。我不知道为什么它会以这种方式工作。 如果有人知道,请写信,提前谢谢! 我的测试看起来是这样:
test('modal', () => {
const handleClose = jest.fn();
const {getByText} = render(<Modal onClose={handleClose} isOpen title={'title'} />);
expect(getByText('title')).toBeTruthy();
});
我的组件如下所示:
interface IModalProps {
isOpen: boolean;
title?: string;
className?: string;
onClose: () => void;
content?: React.ReactChildren | React.ReactChild
}
const Modal = ({isOpen, title, content, onClose, className}: IModalProps) => {
const keydownHandler = ({keyCode}:KeyboardEvent) => {
if (keyCode === 27) {
onClose();
}
};
React.useEffect(() => {
document.addEventListener('keydown', keydownHandler);
return () => document.removeEventListener('keydown', keydownHandler);
});
const modalInPortal = () => (
<div
className={classNames(
'modal-overlay',
isOpen && 'active')}
onClick={onClose}
>
<div
className={classNames(
className,
'modal' )}
onClick={(e) => e.stopPropagation()}
>
<div className="modal-block-content">
<span
className="close-btn"
onClick={onClose}
>
×
</span>
<h2 className="modal-title">{title}</h2>
{content && <div className="modal-body">{content}</div>}
<div className="modal-footer">
<Button
color={'light'}
style={{color:'blue'}}
size="lg"
onClick={onClose}
>
Cancel
</Button>
<Button size="lg">Save</Button>
</div>
</div>
</div>
</div>
);
return createPortal( modalInPortal(), document.getElementById('portal'));
};
最有可能的是,在生产中,您的index.html
中有一个 HTML 元素,其id
为portal
。
Jest 没有相同的 HTML,所以当它尝试传送时,它找不到它并爆炸了。
通常要解决此问题,您需要在 jest 配置中添加一个setupFilesAfterEnv
,该配置指向一个新文件,该文件在反应范围之外构建该 HTML。
在此文件中,您有:
const portalEl = document.createElement('div')
portalEl.setAttribute('id', 'portal')
document.body.appendChild(portalEl)
现在,对于所有测试,测试环境就像您的真实环境一样(此文件是全局应用的)。
断言内容时,您可能还需要使用screen
,因为实际模态是在容器外部加载的。