2017-01-26 2 views
4

sagen, dass ich die folgende Anwendung haben:Wie kann der Rückruf von Komponenten, der durch den Rückruf von untergeordneten Komponenten aufgerufen wird, in Reaktion mit Enzym getestet werden?

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)} />; 
    } 
} 

ich die Parent Komponente zu testen, um die richtige Art und Weise herauszufinden, eine harte Zeit. Die Child und App man kein Problem, aber die Parent ...

Ich meine, wie kann ich testen, dass ein Klick auf die Child Komponente wird den Parent Klick Rückruf aufzurufen, ohne:

  1. ... Rendering Child. Parent sollte isoliert als flacher Renderer getestet werden. Child wird auch isoliert getestet und wenn ich ein Mounten rendern, teste ich grundsätzlich den Klick-Callback auf der Child zweimal.
  2. ... direkt handleParentOnClick auf der Parent Instanz aufrufen. Ich sollte nicht auf die genaue Implementierung von Parent für diese abhängen. Wenn ich den Namen der Callback-Funktion ändere, bricht der Test ab und es könnte sehr wohl ein false positives sein.

Gibt es eine dritte Option?

Antwort

5

Während Parent testen, können Sie tun:

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 
    }); 
}); 
+2

Die 'find' -Methode von Enzyme akzeptiert eine React-Klasse als Selektor, also möchten Sie wahrscheinlich die Anführungszeichen um' Child' (Zeile 8) entfernen. Abgesehen davon ist dies fast wörtlich, dass die Antwort ich geben würde –

+0

Dies war die Antwort, die ich suchte, vielen Dank =) @ JordanBonitatis Das wird einen zusätzlichen Import erfordern, während das Zitat Beispiel nicht. Abgesehen davon, dass eine Zeichenkette fehleranfälliger ist, gibt es einen anderen Vorteil, wenn Sie eine Klasse gegen eine Zeichenkette als Selektor übergeben? –

0

Ich denke, das könnte Ihnen eine Idee geben.

// Komponente

class Child extends React.Component { 
    render() { 
    return <button onClick={this.handleChildOnClick} className="t-btn">{this.props.children}</button>; 
    } 
    handleChildOnClick() { 
    this.props.onChildClick('foo'); 
    } 
} 

// Test-

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); 
    }); 
}); 

Um zu testen, Eltern mit Kind Komponente

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); 
    }); 
}); 

Above Code nur nur eine Komponente handhaben, aber ich hoffe, dies könnte Gib dir etwas Wichtiges. Sorry, wenn die Syntax überall bricht ..

+0

Das ich suchte nicht die Antwort war ... Sie testen gerade die 'Child' Komponente, nicht die "Eltern" (worum es in der Frage ging). Vielen Dank für Ihren Beitrag. –

+1

Nicht schwierig, das zu testen. Aktualisiert die Antwort – anoop

+1

@RicardoAmaral hat es jetzt aktualisiert – anoop

Verwandte Themen