简体   繁体   中英

React testing state of component with Jest and Enzyme

I have a simple component where you click a button and it uses fetch to call an API and log the result:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {isLoading: false};
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({isLoading: true});
    return fetch('https://api.github.com/users/londonappdev')
      .then(res => {
        return res.json();
      })
      .then(data => {
        console.log(data);
        this.setState({isLoading: false})
      });
  }

  render() {
    return (
      <div className="App">
        <button onClick={this.handleClick}>Click</button>
      </div>
    );
  }
}

I am trying to test that isLoading is set to true while the request is in progress and then is set to false once the request is complete.

My test looks like this:

it('sets isloading to true while loading', () => {
  global.fetch = jest.fn().mockReturnValue(Promise.resolve({
    ok: true,
    json: () => Promise.resolve({'user': 'test'})
  }));

  const c = shallow(<App />);
  c.instance().handleClick().then(() => {
    expect(c.instance().state.isLoading).toEqual(false);
  });
  expect(c.instance().state.isLoading).toEqual(true);
});

This works, however my question is: Is it safe/reliable to test state this way? Since setState is asynchronous, is it possible that expect(c.instance().state.isLoading).toEqual(true); would be called before the state is properly set?

Any advice on the best way to test this type of component would be much appreciated.

Yes that's perfectly safe. Similarly to setTimeout(callback, 0) , promise callbacks are queued to run after the rest of the synchronous code. This ensures your assertions will run at the correct points in your program.

Small tip for unit testing - instead of calling c.instance().handleClick() I would call c.find('button').prop('onClick')() . Your component is the "unit" that you're testing and so you should try to avoid accessing internal methods / properties

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM