Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to stub out or spy on the setState method in React when doing unit tests?

I have the following function in my component:

method(args) {
 fetch(args)
  .then((response) => {
    this.setState({
      element: response
      error: false
    });
  })
  .catch((error) => {
    this.setState({
      error: true
    });
  });
}

I am trying to write a unit test for it so I have mocked out the fetch call using fetch-mock with a custom response. I want to check if the state was updated when this method is called and it doesn't seem to be working. I am using enzyme, expect, and sinon and have been unsuccessful in getting the spy to be called when I set component.setState = sinon.spy or stubbing it out. How can I check to see if setState was called with certain elements or is my approach to unit testing this wrong?

like image 268
intuition17 Avatar asked Apr 29 '17 23:04

intuition17


People also ask

What happens on setState React?

Inside it, the Clock component schedules a UI update by calling setState() with an object containing the current time. Thanks to the setState() call, React knows the state has changed, and calls the render() method again to learn what should be on the screen.

What happens when you call setState ()?

What setState does? setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses.

What can be passed to setState?

The second argument that can optionally be passed to setState is a callback function which gets called immediately after the setState is completed and the components get re-rendered.

Does setState have a callback?

The setState function takes an optional callback parameter that can be used to make updates after the state is changed. This function will get called once the state has been updated, and the callback will receive the updated value of the state.


1 Answers

Assuming the method is called when the component mounts and the method has been stubbed, try this:

it('should update state with response', () => {
  const wrapper = mount(<Component />);

  return Promise.resolve().then(() => {
    expect(wrapper.state('error')).to.be.false;
  });
});

Returning a promise allows you to test async behaviour in a less hacky way than using a callback in a setTimeout.

I use sinon for stubs, so I'd have something like this in the test:

sinon.stub(window, 'fetch').resolves(mockedResponse);
like image 52
nevace Avatar answered Sep 29 '22 01:09

nevace