如何使用酶、笑话和反应测试材料设计事件监听器
Posted
技术标签:
【中文标题】如何使用酶、笑话和反应测试材料设计事件监听器【英文标题】:How to test material design event listener using enzyme, jest and react 【发布时间】:2019-01-20 17:15:22 【问题描述】:我正在测试模拟函数 (onAccept) 的调用,该函数应在单击 Accept 按钮时执行(类名为 mdc-dialog__footer__button--accept
的那个)。我尝试了我所知道的一切,但没有运气。这在(非测试)开发环境中完全正常。
我总是收到以下错误:
期望(jest.fn()).toHaveBeenCalled() 预期的模拟函数已被调用,但未被调用。
任何想法我做错了什么?
这是我的 Dialog.tsx 组件,它包装了材质对话框:
import MDCDialog from '@material/dialog';
import * as React from 'react';
import RefObject from 'react';
import IDialogProps from '.';
export class Dialog extends React.Component<IDialogProps, any>
private dialogRef: RefObject<htmlDivElement>;
private dialog: MDCDialog;
public componentWillMount()
const elementRef = this.props.elementRef;
this.dialogRef = elementRef ? elementRef : React.createRef();
public render()
const
elementRef,
className,
children,
role,
isVisible,
onClose,
onAccept,
onCancel,
...other
= this.props;
return (
<aside
ref= this.dialogRef
className= this.getClassName()
role="alertdialog"
...other
>
<div className="mdc-dialog__surface">
...children
</div>
<div className="mdc-dialog__backdrop"></div>
</aside>
);
public componentDidMount()
const
onAccept,
onCancel,
onClose,
isVisible
= this.props;
this.dialog = new MDCDialog(this.dialogRef.current);
if (onAccept)
this.dialog.listen("MDCDialog:accept", onAccept);
if (onCancel)
this.dialog.listen("MDCDialog:cancel", onCancel);
if (onClose)
this.dialog.listen("MDCDialog:accept", onClose);
this.dialog.listen("MDCDialog:cancel", onClose);
if (isVisible)
this.dialog.show();
public componentDidUpdate(prevProps: IDialogProps)
if (prevProps.isVisible !== this.props.isVisible)
this.toggleVisibility();
private toggleVisibility = () =>
const isVisible = this.props.isVisible;
isVisible ? this.dialog.show() : this.dialog.close();
private getClassName = (): string =>
const
className
= this.props;
let result = "mdc-dialog";
result += className ? ` $className` : "";
return result;
这是我的测试:
test("should execute onAccept on 'accept' button of dialog click", () =>
const onAccept = jest.fn();
const component = (
<Dialog onAccept= onAccept isVisible>
<button id="cancelButton" className="mdc-dialog__footer__button--cancel">Cancel</button>
<button id="acceptButton" className="mdc-dialog__footer__button--accept">Accept</button>
</Dialog>
);
const wrapper = mount(component);
wrapper.find("#acceptButton").at(0).simulate("click");
expect(onAccept).toHaveBeenCalled();
);
重要的事实是MDCDialog.listen("MDCDialog:accept", onAccept)
将“MDCDialog:accept”自定义事件放在<aside>
元素上。那么问题来了,有没有什么方法可以测试模拟函数的调用,或者至少检查自定义事件是否已附加?
【问题讨论】:
【参考方案1】:经过几天的研究,我找不到答案。但是,最后,我通过使用ReactDOM.render()
将组件附加到文档正文来做到这一点。这可能不是最好的解决方案,但它似乎有效。这是解决方案:
test("should execute onAccept on accept button of dialog click", () =>
const onAccept = jest.fn();
const component = (
<Dialog onAccept= onAccept isVisible>
<button id="cancelButton" className="mdc-dialog__footer__button--cancel">Cancel</button>
<button id="acceptButton" className="mdc-dialog__footer__button--accept">Accept</button>
</Dialog>
);
ReactDOM.render(component, document.body);
const el = document.getElementById("acceptButton");
el.click();
expect(onAccept).toHaveBeenCalled();
);
我仍然不确定为什么前面的示例不起作用。
【讨论】:
以上是关于如何使用酶、笑话和反应测试材料设计事件监听器的主要内容,如果未能解决你的问题,请参考以下文章