【问题标题】: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”自定义事件放在&lt;aside&gt; 元素上。那么问题来了,有没有什么方法可以测试模拟函数的调用,或者至少检查自定义事件是否已附加?

【问题讨论】:

    标签: reactjs material-design jestjs


    【解决方案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();
    });
    

    我仍然不确定为什么前面的示例不起作用。

    【讨论】:

      猜你喜欢
      • 2021-01-05
      • 2020-06-14
      • 2017-08-18
      • 2018-03-23
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 2018-08-24
      • 2019-04-05
      相关资源
      最近更新 更多