How to test component callback caused by child component callback in React with Enzyme?

Let's say I have the following application:

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

I find it difficult to determine the correct way to test the Parent component. Child and App are not a problem, but Parent ...

I mean, how to verify that clicking on the Child component will call the Parent callback without:

  • ... rendering of a Child . Parent should be tested in isolation as a small render. Child will also be tested in isolation, and if I do a mount render, I basically test the click callback on Child twice.
  • ... directly calls handleParentOnClick on the Parent instance. I should not depend on the exact implementation of Parent for this. If I change the name of the callback function, the test will break, and this can be very false.

Is there a third option?

+5
source share
2 answers

When testing Parent you can:

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

I think this may give you some idea.

//Component

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

To test a parent with a child component

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

Only one component is simply being processed on the code, but I hope this can give you some meaning. Sorry if the syntax breaks anywhere.

0
source

Source: https://habr.com/ru/post/1263370/


All Articles