使用Mocha测试承诺时未捕获(承诺)错误

时间:2017-11-27 07:48:11

标签: javascript promise mocha chai

我很难测试基于承诺的功能。我使用Mocha作为测试框架和断言框架的chai库。我是摩卡和柴的新手。我遇到的问题很少,我不知道我的代码是不对的。也许我的测试方法完全错了,也许有人帮忙。

我因为期望而得到未捕获(保证)错误,但实际上我不知道我的方式是否是测试这些功能的正确方法。

这是我的returnResult函数,它解析了一个值 - >一个字符串

var returnResult = function (stateParamName, stateParamValue) {

 return new Promise((resolve, reject) => {
   peer3.get({ path: { equals: 'todo/#0' } }).then(function (results) {
    console.log(stateParamName + ': ' + results[0].value[stateParamName])
    resolve(results[0].value[stateParamName]);
  });
});
}

这是我的摩卡测试

 describe("Call Tests Suite", function () {
  describe("Basic Call Test", function () {
  it("Call status for both side should be IN CALL", function () {
  peer3.call('login/add', ['testaccount1'])
    .then(() => peer3.call('todo/makeCall1', ['testaccount2@testdomain.com']))
    .then(() => checkResult('state_term', 'RINGING'))
    .then((interval) => { clearInterval(interval); peer3.call('todo/answerCall2', ['empty']) })
    .then(() => checkResult('state_term', 'IN_CALL'))
    .then((interval) => clearInterval(interval))
    //.then(console.log('test sonucu: ' + returnResult('state_term', 'IN_CALL')))
    .then(returnResult('state_term', 'IN_CALL'))
    .then((result) => expect(result).to.equal('IN_CALL'))        
   });

 });

如你所见,我只使用断言获得最后的结果。也许我应该将整个测试作为承诺函数进行测试。有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

我不知道你的错误来自哪里。但是,您的代码中有很多东西可以改进,并且可能会让您进行更好的调试,因此您可以找到错误:

1-您应该在promise链的末尾添加一个.catch处理程序。 ' 未捕获错误'指的是:您的then处理程序中有一个错误,但它没有被catch捕获。您应该在火车末尾添加catch电话:

describe("Call Tests Suite", function () {
describe("Basic Call Test", function () {
it("Call status for both side should be IN CALL", function () {
peer3.call('login/add', ['testaccount1'])
    .then(() => peer3.call('todo/makeCall1', ['testaccount2@testdomain.com']))
    .then(() => checkResult('state_term', 'RINGING'))
    .then((interval) => { clearInterval(interval); peer3.call('todo/answerCall2', ['empty']) })
    .then(() => checkResult('state_term', 'IN_CALL'))
    .then((interval) => clearInterval(interval))
    //.then(console.log('test sonucu: ' + returnResult('state_term', 'IN_CALL')))
    .then(returnResult('state_term', 'IN_CALL'))
    .then((result) => expect(result).to.equal('IN_CALL'))
    .catch(err => {
      console.log(err);//This will allow you better debugging.
    })       
});

});

好的,现在,我们必须记住你的代码是异步的。但是,mocha it函数,默认情况下是同步的:它们不会等待您的异步代码执行。

为了告诉mocha您的测试是异步的,您必须将参数传递给测试。此参数是一个函数,通常称为done,您必须在测试结束时显式调用。否则,您的测试将在到达代码的异步部分之前完成,通常会给您误报。

describe("Call Tests Suite", function () {
describe("Basic Call Test", function () {
it("Call status for both side should be IN CALL", function (done) {
peer3.call('login/add', ['testaccount1'])
    .then(() => peer3.call('todo/makeCall1', ['testaccount2@testdomain.com']))
    .then(() => checkResult('state_term', 'RINGING'))
    .then((interval) => { clearInterval(interval); peer3.call('todo/answerCall2', ['empty']) })
    .then(() => checkResult('state_term', 'IN_CALL'))
    .then((interval) => clearInterval(interval))
    //.then(console.log('test sonucu: ' + returnResult('state_term', 'IN_CALL')))
    .then(returnResult('state_term', 'IN_CALL'))
    .then((result) => expect(result).to.equal('IN_CALL'))
    .then( () => {
        done(); //dont use .then(done) or things may break due to extra 
        parameter
    })
    .catch( err => {
         console.log(err);
         done(err); //passing a parameter to done makes the test fail.
    })       
});

});

但是,我们必须解决您的代码问题。 then方法需要函数作为参数。但是,在这一行:     .then(returnResult(' state_term',' IN_CALL'))

你正在传递给returnResult('state_term', 'IN_CALL')的一个电话,它不是一个函数,而是一个承诺。你应该传递一个函数 - 然后返回promise - :

.then(() => returnResult('state_term', 'IN_CALL')) //now the parameter to 
       //then is a function that return a Promise, not a Promise itself.

另外,正如你在交流中被告知的那样,你明确地返回了一个新的Promise,它包含了你return result函数中的一个Promise:根本不需要它,而且这个函数可以写成:

var returnResult = function (stateParamName, stateParamValue) {
    return peer3.get({ path: { equals: 'todo/#0' } }).then(function (results) {
        console.log(stateParamName + ': ' + results[0].value[stateParamName]);
        return(results[0].value([stateParamName]));
    });
}

但是,您的代码中有很多内容似乎很奇怪(我根本不确定setinterval调用的原因),所以我对测试非常有信心不会像你期望的那样工作。您应该首先熟悉Promises和异步mocha测试,并且不要尝试测试真正长的异步操作序列。祝你好运!