How to wait for a promise in the Gesture Response Test?

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

Here is some of the code that gets called when the user clicks 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 I am using moker from MyService

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

      

Here is my layout code:

//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 is not working correctly :-)

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

My problem is how to wait for the promise function to fire before waiting for the result?

Thank you in advance

+3


source to share


1 answer


Just guess: try adding a callback done

.

// 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 wait in try-catch because waiting for a throw on error and the test failing will result in done

not being called.

Also see the dest docs for more advanced examples .

+3


source







All Articles