如何在Jest React测试中等待承诺?

时间:2017-04-18 20:15:27

标签: javascript reactjs unit-testing promise jestjs

我想用Jest和Enzyme测试一个React组件。此组件是一个登录表单,当用户单击登录按钮时,我想根据结果检查对象模型是否相应地更新了对象模型。

以下是用户点击提交按钮时调用的代码部分。

// 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});
  });
};

我写了一个Jest测试。这是代码:

// 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);
});

为了测试它,我使用模拟MyService

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

以下是我的模拟代码:

//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();

测试失败了: - )

我的问题是:如何从我的测试中删除setTimeout()调用?有没有更好的方法来测试这个基于承诺的功能。

我的问题是如何在期望结果之前等待promise函数失败?

提前致谢

1 个答案:

答案 0 :(得分:5)

只是预感:尝试添加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);
});

你需要在try-catch中包含期望值,因为期望抛出错误并且测试失败将导致done不被调用。

另请参阅more extended examples的jest文档。