简体   繁体   中英

How to wait for promise in Jest React test?

I want to test a React component with Jest and Enzyme. This component is a login form and when the user clicks on the login button, I want to check that depending the result, the object model is well updated accordingly.

Here is the part of the code that is called when the user clicks on on the submit button.

// Login.jsx
handleSubmit(e) {

  var that = this;

  this.setState({stateResult: "", errorLabel: ""});

  if(e) {
    e.preventDefault();
    e.stopPropagation();
  }

  MyService.login(this.state.email, this.state.password).then(function(account) {
    that.setState({stateResult: "login-ok", errorLabel: ""});
  }).catch(function(err) {
    that.setState({stateResult: "login-error", errorLabel: err.data.message});
  });
};

I wrote a Jest test. Here is the code:

// Login-test.js
test('that when the signin fails, the stateResult model is updated with login-error', () => {

    const wrapper = shallow(<Landing />);
    wrapper.find('a#landingjsx-signin').simulate('click');

    wrapper.update();
    setTimeout(function() {
        expect(wrapper.state().stateResult).toEqual("login-error");
    }, 100);
});

For testing it, I use a mock of MyService

jest.mock('../../../modules/MyService.js');

Here is the code of my mock:

//MyService.js
class MyService {

  constructor() {

  }

  login(user, password) {

    return new Promise((resolve, reject) => {

        process.nextTick(() => {
            if(user === "aaa") {
                resolve({});
            }
            else {
                reject({
                    data: {
                        message: "bad-password"
                    }
                });
            }
        });
    });
  }
}

export default new MyService();

The test fails right :-)

My question is: How to remove the setTimeout() call from my test ? Is there a better way to test this promise based function.

My problem is how to wait for the promise function to fail before expecting the result ?

Thanks in advance

Just a hunch: try adding the done callback.

// Login-test.js
test('that when the signin fails, the stateResult model is updated with login-error', (done) => {

    const wrapper = shallow(<Landing />);
    wrapper.find('a#landingjsx-signin').simulate('click');

    wrapper.update();
    setTimeout(function() {
        try {
          expect(wrapper.state().stateResult).toEqual("login-error");
          done()
        } catch (e) {
          done.fail(e)
        }
    }, 100);
});

You need to wrap the expectation in try-catch, because expect throws on error and a test failure will cause done not to be called.

Also see the jest docs for more extended examples .

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