如何使用Enzyme浅层封装器对作为道具传递给子组件的React函数进行单元测试

时间:2019-07-12 06:46:31

标签: javascript reactjs jestjs enzyme

我对前端开发人员非常陌生,在使用Shallow进行酶单位测试时遇到了一些麻烦。基本上,我有类似

class MyComponent extends React.Component {
    constructor(props, context) {
        super(props, context);
    }

    render() {
        const {
            handleClick,
            ...other
        } = this.props;

        return (
            <div className="someClass">
                // a bunch of stuff
                <div className="buttonArea">
                    <MyComponentChild onClick={handleClick} />
                </div>
            </div>
        );
    }

    MyComponent.propTypes = {
        handleClick: PropTypes.func.isRequired,
        ...other
    };

    export default MyComponent;
}

handleClick是在MyComponent所属的容器(即ComponentContainer)中定义的回调函数。我将它作为道具传递给MyComponent,然后传递给MyComponentChild(这是一个按钮组件)。我想测试在单击MyComponentChild时是否触发handleClick。

我目前的酶测

it('handleClick should fire when clicked', () => {
    const mockCallbackFn = jest.fn();
    const wrapper = shallow(<MyComponent {handleClick = { mockCallbackFn }} />);
    wrapper.find('MyComponentChild').simulate('click');
    expect(mockCallbackFn).toHaveBeenCalled();
});

但是,此测试当前失败,因为显然从未调用过mockCallbackFn。但是,这也正在过去

expect(wrapper.find('MyComponentChild').prop('handleClick')).toEqual(mockCallbackFn);

我在做什么错?任何帮助,不胜感激!

2 个答案:

答案 0 :(得分:0)

您需要使用mount而不是shallowshallow仅装载第一级组件,因此不会装载ComponentChild,也不会传递点击处理程序。

您可以在debug()上调用wrapper,然后console.log对其进行查看。

答案 1 :(得分:0)

simulate(someEventName)确实很简单:它调用名称为"on" + someEventName的prop。因此simulate('click')运行.props().onClick()

但是您的组件使用handleClick道具,这就是为什么simulate()不会调用它的原因

wrapper.find('MyComponentChild').props().handleClick();

名称simulate令人困惑,以至于团队打算将其删除(https://github.com/airbnb/enzyme/issues/2173)。

旁注:声明道具时不需要多余的花括号。我的意思是{handleClick = { mockCallbackFn }}最好是handleClick={mockCallbackFn},因为它是React代码的典型特征,看起来也不太混乱。