Node.js Assert正在破坏Mocha测试中的异步函数
我正在构建一个节点模块,并尽我所能对其进行单元测试。我已经安排摩卡和柴做测试处理。我在测试异步方法(返回承诺的方法)时遇到问题 在下面的测试中,我正在“升级”对象上测试一个方法Node.js Assert正在破坏Mocha测试中的异步函数,node.js,testing,promise,mocha.js,Node.js,Testing,Promise,Mocha.js,我正在构建一个节点模块,并尽我所能对其进行单元测试。我已经安排摩卡和柴做测试处理。我在测试异步方法(返回承诺的方法)时遇到问题 在下面的测试中,我正在“升级”对象上测试一个方法 getVersions()调用返回一个承诺,因为该方法是异步的。当承诺解析时,我想测试versions变量中返回的值 assert(versions&&versions.length>0,'应该至少有一个版本')是实际测试。我添加了assert.equal(1,2)
getVersions()
调用返回一个承诺,因为该方法是异步的。当承诺解析时,我想测试versions
变量中返回的值
assert(versions&&versions.length>0,'应该至少有一个版本')代码>是实际测试。我添加了assert.equal(1,2)因为我注意到当测试失败时,测试用例甚至不会出现在测试列表中
我假设assert调用抛出了一个Mocha应该接收的异常。然而,它被困在promisesthen
handler函数中
这是怎么回事?为什么当断言将在该方法中失败时,它不会在列表中显示测试用例(它不会显示为失败;就像它不存在一样)?在调用回调之前,测试不会显示在列表中,如果断言失败,则决不会发生这种情况。您需要在最终承诺中调用.catch(done)
,以确保始终调用done
如果您给它一个超时值,测试就会显示出来,您可能应该这样做
总之,mocha
理解承诺。您根本不需要处理回调:
it('Should return a list of versions for the default git repo', function () {
fs.writeFileSync(appSetup.CONFIG_FILENAME, JSON.stringify(appSetup.DEFAULT_CONFIG));
var upgrade = new Upgrade({
quiet: true
});
return upgrade.getVersions().then(function (versions) {
assert(versions && versions.length > 0, 'Should have at least one version.');
assert.equal(1, 2);
});
});
问题的核心在于,您拥有的代码基本上是:
try {
var versions = upgrade.getVersions();
} catch (err){
return done(err);
}
assert(versions && versions.length > 0, 'Should have at least one version.');
assert.equal(1, 2); // this throws the exception which causes the test case not even exist
done();
考虑到这一点,应该很清楚,如果断言抛出,那么两个回调都不会运行
try {
var versions = upgrade.getVersions();
assert(versions && versions.length > 0, 'Should have at least one version.');
assert.equal(1, 2); // this throws the exception which causes the test case not even exist
done();
} catch (err){
return done(err);
}
更像是你想要的,那就是:
upgrade.getVersions().then(function (versions) {
assert(versions && versions.length > 0, 'Should have at least one version.');
assert.equal(1, 2); // this throws the exception which causes the test case not even exist
}).then(done, done);
节点,该节点将执行断言,然后将回调移动到始终处理错误的辅助.then()
这就是说,将承诺作为回报要容易得多
return upgrade.getVersions().then(function (versions) {
assert(versions && versions.length > 0, 'Should have at least one version.');
assert.equal(1, 2); // this throws the exception which causes the test case not even exist
});
让摩卡在没有回调的情况下监控承诺本身。我不知道为什么这个答案有效。原始代码基本上是:async().then(function(){throw new Error();//如果此行抛出,则传递给.catch()处理程序done();})。catch(done)//将done()注册为错误处理程序。如果发生抛出,则不会执行then()
处理程序中的done()
调用,而是调用.catch()
处理程序。。。这仍然是完成的
。哎哟,注释不允许代码块和5分钟后锁定。很抱歉,这是一个垃圾格式:(.then(fn,done)
与.then(fn).catch(done);
,这是区别的核心。在第一个iffn
抛出时,这是一个未处理的错误,在第二个示例中,调用了done
。您的意思是当代码在里面时。then()如果失败,它将不会触发第二个参数?是的,确实如此,因此在问题中,assert
抛出而done
从未被调用,因此解决方案是将done
处理程序移动到始终被调用的位置,无论是错误还是其他。
return upgrade.getVersions().then(function (versions) {
assert(versions && versions.length > 0, 'Should have at least one version.');
assert.equal(1, 2); // this throws the exception which causes the test case not even exist
});