断言在摩卡testing中打破asynchronousfunction

我正在构build一个节点模块,并试图尽我所能对它进行unit testing。 我已经设置了摩卡和柴做testing处理。 我有一个问题,testing我的asynchronous方法(返回承诺的方法)。

在下面的testing中,我正在testing一个“升级”对象的方法。

it('Should return a list of versions for the default git repo', function (done) { fs.writeFileSync(appSetup.CONFIG_FILENAME, JSON.stringify(appSetup.DEFAULT_CONFIG)); var upgrade = new Upgrade({ quiet: true }); 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 done(); }, done); }); 

getVersions()调用返回一个promise,因为这个方法是asynchronous的。 当承诺解决时,我想testingversionsvariables中返回的值。

assert(versions && versions.length > 0, 'Should have at least one version.'); 是实际的testing。 我加了assert.equal(1, 2); 因为我注意到当testing失败时testing用例甚至不会显示在testing列表中。

我假设断言调用抛出一个例外,摩卡应该拾取。 然而它被困在承诺then处理函数。

这里发生了什么? 为什么当assert在那个方法中失败时,它不会在列表中显示testing用例(它不会显示为失败;就像它不存在一样)?

问题的核心是你所拥有的代码本质上是:

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

看这个,应该清楚的是,如果断言抛出,那么两个callback都不会运行。

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

节点,这将执行断言,然后将callback移动到一个辅助.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 }); 

让摩卡在没有callback的情况下监督自己的承诺。

在调用callback之前,testing不会显示在列表中,如果该断言失败,则不会发生这种情况。 您需要在最终的承诺上调用.catch(done) ,以确保始终调用done

如果你给它一个超时值,那么testing显示出来,你应该这样做。

所有这一切, mocha理解诺言。 根本不需要处理callback:

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