我正在测试模拟函数(onAccept)的调用,该函数应在 Accept 按钮单击(类名为mdc-dialog__footer__button--accept
的按钮)上执行。我尝试了我所知道的一切,但是没有运气。在(非测试)开发环境中,这一切都可以正常工作。
我总是遇到以下错误:
expect(jest.fn())。toHaveBeenCalled()
预期的模拟函数已被调用,但未被调用。
有什么主意我在做错什么吗?
这是我的Dialog.tsx组件,用于包装材料Dialog:
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)
在<aside>
元素上放置了“ MDCDialog:accept”自定义事件。因此,问题是,是否有任何方法可以测试模拟函数的调用,或者至少检查是否已附加自定义事件?
答案 0 :(得分:0)
经过几天的研究,我找不到答案。但是,最后,我通过使用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();
});
我仍然不确定为什么前面的示例不起作用。