Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test React Component shouldComponentUpdate method

Tags:

I have a React Component that implements the shouldComponentUpdate method and I'd like to unit test it. Ideally I could change some prop or state on the component in a unit test and verify it either re-rendered or not. I am using enzyme if that helps.

like image 366
Liron Yahdav Avatar asked May 26 '17 23:05

Liron Yahdav


People also ask

Why do we use shouldComponentUpdate () function in Reactjs?

The shouldComponentUpdate method allows us to exit the complex react update life cycle to avoid calling it again and again on every re-render. It only updates the component if the props passed to it changes.

What is shouldComponentUpdate in react?

shouldComponentUpdate(nextProps, nextState) Use shouldComponentUpdate() to let React know if a component's output is not affected by the current change in state or props. The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior.

What is nextState in shouldComponentUpdate?

nextState is for detecting if the component should update based on the upcoming state just like you mentioned. This helps to optimize updating components.


2 Answers

I would probably just call shouldComponentUpdate directly.

Something like

const comp = shallow(<Comp {...props} />) const shouldUpdate = comp.instance().shouldComponentUpdate(nextProps, nextState) expect(shouldUpdate).toBe(true/false) 

Trying to test by determining if the component actually rendered/didn't render is probably more trouble than it's worth; I'm not even sure how you would do that using enzyme. You can't really go off of the rendered output, since you would probably not return false from shouldComponentUpdate unless the rendered output was the same as before. So determining if a render occurred or not couldn't come from the output alone.

Testing by calling it directly seems fine to me though. As long as you trust React is going to use your shouldComponentUpdate return value correctly (we have bigger problems if it doesn't), it's safe.

like image 102
TLadd Avatar answered Sep 19 '22 17:09

TLadd


You probably dont want to test shouldComponentUpdate as isolated function when you already know what the outcome is.

As it mentioned in the documentation you can use setProps or setState and this is probably - at least for me - a better approach to expect the exact outcome from your component when updating related values.

In your MyComponent.test.js

import { expect } from 'chai'; import sinon from 'sinon-sandbox'; import { shallow } from 'enzyme';  it('updates when changing state or props', () => {   const wrapper = shallow(<MyComponent />);    const shouldComponentUpdate = sinon.spy(MyComponent.prototype, 'shouldComponentUpdate');    expect(shouldComponentUpdate).to.have.property('callCount', 0);    wrapper.setProps({ propThatWillUpdateTheComp: 'foo' });    // or in case you are testing component update in case of state change   // wrapper.setState({ stateThatWillUpdateTheComp: 'bar' });    expect(shouldComponentUpdate).to.have.property('callCount', 1);    expect(shouldComponentUpdate.returned(true)).to.be.equal(true);  }); 
like image 39
Jalal Avatar answered Sep 17 '22 17:09

Jalal