everyone.
I\'m having weird issues with testing a state update after an async call happening in componentDidMount
.
Here\'s my component code:
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..