断言在摩卡测试中打破异步函数

Mik*_*e G 7 testing mocha.js node.js promise

我正在构建一个节点模块,我正在尽力对其进行单元测试.我已经设置了mocha和chai来进行测试处理.我在测试我的异步方法(返回promises的方法)时遇到问题.

在以下测试中,我正在测试"升级"对象上的方法.

  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);
  });
Run Code Online (Sandbox Code Playgroud)

getVersions()调用返回一个promise,因为该方法是异步的.当promise解析时,我想测试versions变量中返回的值.

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

我假设断言调用抛出了Mocha应该拾取的异常.然而它被困在promises then处理函数中.

这里发生了什么?为什么当断言在该方法中失败时,它不会在列表中显示测试用例(它没有显示为失败;就像它不存在一样)?

log*_*yth 11

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

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();
Run Code Online (Sandbox Code Playgroud)

看一下,应该很清楚,如果断言抛出,那么两个回调都不会运行.

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);
}
Run Code Online (Sandbox Code Playgroud)

更像你想要的,这将是:

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);
Run Code Online (Sandbox Code Playgroud)

节点,它将执行断言,然后将回调移动到.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
});
Run Code Online (Sandbox Code Playgroud)

让Mocha在没有回调的情况下监控承诺.


Aar*_*our 5

在您调用回调之前,测试不会显示在列表中,如果该断言失败,则不会发生这种情况。您需要调用.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);
    });
  });
Run Code Online (Sandbox Code Playgroud)