Unit testing 如何测试子组件回调在React with Ezyme中调用的组件回调?

Unit testing 如何测试子组件回调在React with Ezyme中调用的组件回调?,unit-testing,reactjs,callback,jestjs,enzyme,Unit Testing,Reactjs,Callback,Jestjs,Enzyme,假设我有以下应用程序: class Child extends React.Component { render() { return <button onClick={this.handleChildOnClick}>{this.props.children}</button>; } handleChildOnClick() { this.props.onChildClick('foo'); } } c

假设我有以下应用程序:

class Child extends React.Component {
    render() {
        return <button onClick={this.handleChildOnClick}>{this.props.children}</button>;
    }

    handleChildOnClick() {
        this.props.onChildClick('foo');
    }
}

class Parent extends React.Component {
    render() {
        return <Child onChildClick={this.handleParentOnClick}>click me</Child>;
    }

    handleParentOnClick(text) {
        this.props.onParentClick(12345);
    }
}

class App extends React.Component {
    render() {
        return <Parent onParentClick={(num) => console.log(num)} />;
    }
}
类子级扩展React.Component{
render(){
返回{this.props.children};
}
handleChildOnClick(){
this.props.onChildClick('foo');
}
}
类父类扩展了React.Component{
render(){
返回点击我;
}
handleParentOnClick(文本){
this.props.onParentClick(12345);
}
}
类应用程序扩展了React.Component{
render(){
返回console.log(num)}/>;
}
}
我很难找到测试
父组件的正确方法。
子项
应用程序
都不是问题,但是
父项

我的意思是,如何测试单击
子组件将调用
父组件
单击回调,而无需:

  • …呈现
    子对象
    <代码>父级
  • 应作为浅层渲染单独测试<代码>子项
    也将单独进行测试,如果我执行装载渲染,我基本上会对
    子项
    上的单击回调进行两次测试
  • …直接调用
    handleparenton在
    Parent
    实例上单击
    。为此,我不应该依赖于
    Parent
    的确切实现。如果我更改回调函数的名称,测试将中断,很可能是误报

  • 还有第三种选择吗?

    我想这会给你一些想法

    //组成部分

    class Child extends React.Component {
      render() {
        return <button onClick={this.handleChildOnClick} className="t-btn">{this.props.children}</button>;
      }
      handleChildOnClick() {
        this.props.onChildClick('foo');
      }
    }
    
    类子级扩展React.Component{
    render(){
    返回{this.props.children};
    }
    handleChildOnClick(){
    this.props.onChildClick('foo');
    }
    }
    
    //试验

    import { spy, stub } from 'sinon';
    import { shallow } from 'enzyme';
    
    describe('Child Component', () => {
      it('should check handle click', () => {
        spy(Child.prototype, 'handleChildOnClick');
        const onChildClick = stub();
        const wrapper = shallow(<Child onChildClick={onChildClick}>);
        wrapper.find(".t-btn").simulate('click');
        expect(Child.prototype.handleChildOnClick.callCount).to.equal(1);
      });
    
      it('should check onChildClick', () => {
        const onChildClick = stub();
        const wrapper = shallow(<Child onChildClick={onChildClick}>);
        wrapper.find(".t-btn").simulate('click');
        expect(onChildClick.callCount).to.equal(1);
      });
    });
    
    从'sinon'导入{spy,stub};
    从“酶”导入{shall};
    描述('子组件',()=>{
    它('应检查句柄单击',()=>{
    spy(Child.prototype,'handleChildOnClick');
    const onChildClick=stub();
    常量包装器=浅();
    wrapper.find(“.t-btn”).simulate('click');
    expect(Child.prototype.handleChildOnClick.callCount).to.equal(1);
    });
    它('should check onChildClick',()=>{
    const onChildClick=stub();
    常量包装器=浅();
    wrapper.find(“.t-btn”).simulate('click');
    expect(onChildClick.callCount).to.equal(1);
    });
    });
    
    使用子组件测试父组件的步骤

    import { stub } from 'sinon';
    import { shallow } from 'enzyme';
    import Child from '../Components/Child';
    
    describe('Parent Component', () => {
      it('should check handle click', () => {
        const onParentClick = stub();
        const wrapper = shallow(<Parent onParentClick={onParentClick} />);
        wrapper.find(".t-btn").simulate('click');
        expect(Child.prototype.handleChildOnClick.callCount).to.equal(1);
      });
    
      it('should check onChildClick', () => {
        const onChildClick = stub();
        const wrapper = shallow(<Child onChildClick={onChildClick}>);
        wrapper.find(Child).prop('onChildClick')('foo');
        expect(onParentClick.callCount).to.be.equal(1);
      });
    });
    
    从'sinon'导入{stub};
    从“酶”导入{shall};
    从“../Components/Child”导入子项;
    描述('父组件',()=>{
    它('应检查句柄单击',()=>{
    const onParentClick=stub();
    常量包装器=浅();
    wrapper.find(“.t-btn”).simulate('click');
    expect(Child.prototype.handleChildOnClick.callCount).to.equal(1);
    });
    它('should check onChildClick',()=>{
    const onChildClick=stub();
    常量包装器=浅();
    wrapper.find(Child.prop('onChildClick')('foo');
    expect(onParentClick.callCount).to.be.equal(1);
    });
    });
    

    上面的代码只处理一个组件,但我希望这能给您一些要点。很抱歉,如果语法在任何地方出现错误。

    在测试父级时,您可以执行以下操作:

    import { shallow } from 'enzyme';
    import { stub } from 'sinon';
    
    describe('<Parent/>', () => {
      it('should handle a child click', () => {
        const onParentClick = stub();
        const wrapper = shallow(<Parent onParentClick={onParentClick} />);
        wrapper.find("Child").prop('onChildClick')('foo');
        expect(onParentClick.callCount).to.be.equal(1);
        // You can also check if the 'foo' argument was passed to onParentClick
      });
    });
    
    import{shall}来自“酶”;
    从“sinon”导入{stub};
    描述(“”,()=>{
    它('应该处理子单击',()=>{
    const onParentClick=stub();
    常量包装器=浅();
    wrapper.find(“Child”).prop(“onChildClick”)(“foo”);
    expect(onParentClick.callCount).to.be.equal(1);
    //您还可以检查'foo'参数是否已传递给onParentClick
    });
    });
    
    Enzyme的
    find
    方法接受React类作为选择器,因此您可能希望删除
    Child
    周围的引号(第8行)。除此之外,我给出的答案几乎是一字不差的。这是我一直在寻找的答案,非常感谢=)@JordanBonitatis,这将需要额外的导入,而引用示例则不需要。除了字符串更容易出错之外,作为选择器传递类与字符串相比还有其他优势吗?在子类是MaterialUI组件的情况下,这不适用于我。你脑子里有什么想法吗?为什么?这不是我想要的答案。。。您只是在测试
    子组件
    而不是
    父组件
    组件(问题是关于这个组件的)。谢谢你的贡献。