How to test a prop update on React component
If you re-render the element with different props in the same container node, it will be updated instead of re-mounted. See React.render.
In your case, you should use ReactDOM.render
directly instead of TestUtils.renderIntoDocument
. The later creates a new container node every time it is called, and thus a new component too.
var node, component;
beforeEach(function(){
node = document.createElement('div');
component = ReactDOM.render(<MyComponent value={true} />, node);
});
it('should update the state of the component when the value prop is changed', function(){
// `component` will be updated instead of remounted
ReactDOM.render(<MyComponent value={false} />, node);
// Assert that `component` has updated its state in response to a prop change
expect(component.state.value).toBe(false);
});
Caveat: this won't actually change props.
But for me, all I wanted was to test my logic in componentWillReceiveProps
. So I'm calling myComponent.componentWillReceiveProps(/*new props*/)
directly.
I didn't need/want to test that React calls the method when props change, or that React sets props when props change, just that some animation is triggered if the props differ to what was passed in.
AirBnB's Enzyme library provides an elegant solution to this question.
it provides a setProps method, that can be called on either a shallow or jsdom wrapper.
it("Component should call componentWillReceiveProps on update", () => {
const spy = sinon.spy(Component.prototype, "componentWillReceiveProps");
const wrapper = shallow(<Component {...props} />);
expect(spy.calledOnce).to.equal(false);
wrapper.setProps({ prop: 2 });
expect(spy.calledOnce).to.equal(true);
});