[英]Node.js assert.throws with async functions (Promises)
我想檢查異步函數是否使用本機assert
模塊中的assert.throws
拋出。 我試過
const test = async () => await aPromise();
assert.throws(test); // AssertionError: Missing expected exception..
它(顯然?)不起作用,因為函數在 Promise 被解析之前退出。 然而,我發現這個問題使用回調實現了同樣的事情。
有什么建議嗎?
(我正在使用 Babel 轉換為 Node.js 原生生成器。)
從 Node.js v10.0 開始, assert.rejects
就是這樣做的。
async
函數從不拋出 - 它們返回可能被拒絕的承諾。
您不能將assert.throws
與它們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);
在異步測試用例中。
基於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);
}
}
用法:
it('should throw', async function () {
await assertThrowsAsync(async () => await asyncTask(), /Error/);
});
給出的答案有效,但我今天遇到了這個問題並提出了另一種解決方案,我認為它更簡單一些。
// 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'))
}
由於這個問題仍然受到關注,我想總結一下兩個最佳解決方案,特別是強調新的標准方法。
assert 庫中有一個專用方法assert.rejects
。
來自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);
}
}
您將要使用 Node.js 版本 10 中的新增功能assert.rejects()
。
在高層次上,我們想要的是 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/
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.