Node.js assert.throws with async functions(Promises)

mat*_*apu 16 javascript assert node.js async-await ecmascript-next

我想检查异步函数是否assert.throws从本机assert模块抛出使用.我试过了

const test = async () => await aPromise();
assert.throws(test); // AssertionError: Missing expected exception..
Run Code Online (Sandbox Code Playgroud)

它(obvioulsy?)不起作用,因为函数在Promise解析之前退出.然而我发现了这个问题,使用回调可以实现相同的目标.

有什么建议吗?

(我正在使用Babel转发到Node.js本机生成器)

Ber*_*rgi 22

节点10和更新

从Node.js v10.0开始,assert.rejects就是这样

旧版本的节点

async 函数永远不会抛出 - 它们会返回可能被拒绝的承诺.

你不能使用assert.throws它们.您需要编写自己的异步断言:

async function assertThrowsAsynchronously(test, error) {
    try {
        await test();
    } catch(e) {
        if (!error || e instanceof error)
            return "everything is fine";
    }
    throw new AssertionError("Missing rejection" + (error ? " with "+error.name : ""));
}
Run Code Online (Sandbox Code Playgroud)

并使用它

return assertThrowsAsynchronously(aPromise);
Run Code Online (Sandbox Code Playgroud)

在异步测试用例中

  • 是的,它没有。对困惑感到抱歉。我们正在使用 `npm` 中的 `assert-throws-async` 并替换原生的 `assert.throws`。我错过了它,因为原始文件被替换为不同的文件,并且无需在我的文件中重新导入“assert-throws-async”即可工作。 (2认同)

vit*_*ets 19

根据Bergi的回答,我建议使用原始的assert.throws来获取错误消息的更通用的解决方案:

import assert from 'assert';

async function assertThrowsAsync(fn, regExp) {
  let f = () => {};
  try {
    await fn();
  } catch(e) {
    f = () => {throw e};
  } finally {
    assert.throws(f, regExp);
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

it('should throw', async function () {
    await assertThrowsAsync(async () => await asyncTask(), /Error/);
});
Run Code Online (Sandbox Code Playgroud)

  • 是的,不要在2018年及以后使用它,使用`assert.rejects()`,这里:https://nodejs.org/api/assert.html#assert_assert_rejects_asyncfn_error_message (6认同)
  • 优秀的解决方案,希望这能使官方断言库! (2认同)

mat*_*apu 3

由于这个问题仍然受到关注,我想总结一下两个最佳解决方案,特别是强调新的标准方法。

节点 v10+

断言库中有一个专用方法,assert.rejects.

对于旧版本的 Node

来自vitalets的补充回答:

import assert from 'assert';

async function assertThrowsAsync(fn, regExp) {
  let f = () => {};
  try {
    await fn();
  } catch(e) {
    f = () => {throw e};
  } finally {
    assert.throws(f, regExp);
  }
}
Run Code Online (Sandbox Code Playgroud)