我想检查异步函数是否从本机assert
模块使用assert.throws
引发。
我试过
const test = async () => await aPromise();
assert.throws(test); // AssertionError: Missing expected exception..
它(obvioulsy?)不起作用,因为函数在Promise解析之前退出。 然而我发现这个question使用回调来获得相同的东西。
有什么建议吗?
(我正在使用Babel转发到Node.js原生生成器)
答案 0 :(得分:20)
自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 : ""));
}
并像
一样使用它return assertThrowsAsynchronously(aPromise);
在异步测试用例中
答案 1 :(得分:19)
基于Bergi answer我建议使用原始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);
}
}
用法:
it('should throw', async function () {
await assertThrowsAsync(async () => await asyncTask(), /Error/);
});
答案 2 :(得分:3)
答案是有效的,但我今天遇到了这个问题并提出了另一个解决方案,我觉得这个问题有点简单。
// Code being tested
async function thisFunctionThrows() {
throw new Error('Bad response')
}
// In your test.
try {
await thisFunctionThrows()
assert.equal(1 == 0) // Never gets run. But if it does you know it didn't throw.
} catch (e) {
assert(e.message.includes('Bad response'))
}
答案 3 :(得分:0)
您将要使用assert.rejects()
,它是Node.js版本10中的新增功能。
在更高层次上,我们需要assert.rejects之类的东西,而不是assert.throws,希望您可以接受并运行它:
const assertRejects = (fn, options) => {
return Promise.resolve(fn()).catch(e => {
return {
exception: e,
result: 'OK'
}
})
.then(v => {
if (!(v && v.result === 'OK')) {
return Promise.reject('Missing exception.');
}
if (!options) {
return;
}
if (options.message) {
// check options
}
console.log('here we check options');
});
};
it('should save with error', async () => {
// should be an error because of duplication of unique document (see indexes in the model)
return await assertRejects(async () => {
patientSubscriber = await PatientSubscriber.create({
isSubscribed: true,
patient: patient._id,
subscriber: user._id
});
}, {
message: /PatientSubscriber validation failed/
});
});
答案 4 :(得分:0)
由于这个问题仍在引起人们的注意,我想总结两个最佳解决方案,尤其是强调新的标准方法。
断言库assert.rejects
中有一个专用方法。
来自vitalets answer的填充:
import assert from 'assert';
async function assertThrowsAsync(fn, regExp) {
let f = () => {};
try {
await fn();
} catch(e) {
f = () => {throw e};
} finally {
assert.throws(f, regExp);
}
}