React Enzyme - Test `componentDidMount` Async Call

后端 未结 3 2025
迷失自我
迷失自我 2020-12-09 11:28

everyone.

I\'m having weird issues with testing a state update after an async call happening in componentDidMount.

Here\'s my component code:

3条回答
  •  無奈伤痛
    2020-12-09 12:05

    You can abstract the user list retrieval away from the react component via passing a function that returns a Promise so that instead of

      componentDidMount() {
        request('https://api.github.com/users', (err, res) => {
          if (!err && res.statusCode === 200) {
            this.setState({
              usersList: res.slice(0)
            });
          }
          else {
            console.log(err);
          }
        });
      }
    

    Replace it with

      componentDidMount() {
         var comp = this;
         this.props.getUsers()
            .then(function(usersList) {
              comp.setState({
                usersList: usersList
              });
            })
            .catch(function (err) {
                console.log(err);
            });
      }
    

    And inside your test mock that getUsers function:

        it('Correctly updates the state after AJAX call in `componentDidMount` was made', (done) => {
    
          let resolveGetUsers;
    
          let getUsers = function() {
            return new Promise(function (resolve, reject) {
                      resolveGetUsers = resolve;
                    });
          }
    
          let wrapper = mount();
    
          resolveGetUsers([{ "name": "Reign", "age": 26 }]);
    
    
          // promise resolve happens in a subsequent event loop turn so move assertions inside setImmediate
          setImmediate(() => {
    
            expect(wrapper.update().state().usersList).to.be.instanceof(Array);
            ...
    
            done();
          });
        }
    

    Note that I have done this and it works for me (even without the wrapper.update() part) and here I tried to apply it to your code example without running it..

    Also note that it should work in cases other then componentDidMount too - like having an async action triggered after clicking a button for example..

提交回复
热议问题