断言在摩卡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的。 当承诺解决时,我想testingversions
variables中返回的值。
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); }); });