Node.js assert.throws 具有异步功能(承诺)
Node.js assert.throws with async functions (Promises)
我想使用本机 assert
模块中的 assert.throws
检查异步函数是否抛出异常。
我试过
const test = async () => await aPromise();
assert.throws(test); // AssertionError: Missing expected exception..
它(显然?)不起作用,因为该函数在 Promise 解析之前就退出了。
然而我发现 this question 使用回调可以达到同样的效果。
有什么建议吗?
(我正在使用 Babel 转译为 Node.js 本机生成器。)
节点 10 和更新的节点
从 Node.js v10.0 开始,assert.rejects
就是这样做的。
旧版本的节点
async
函数从不抛出 - 它们 return 承诺可能会被拒绝。
您不能对它们使用 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);
在异步测试用例中。
基于 I've suggest more universal solution that utilizes original 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.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/
});
});
由于问题还在关注中,我想总结一下两个最好的解决方案,特别强调一下新的标准方法。
节点 v10+
断言库中有一个专用方法,assert.rejects
。
对于旧版本的 Node
来自 的填充:
import assert from 'assert';
async function assertThrowsAsync(fn, regExp) {
let f = () => {};
try {
await fn();
} catch(e) {
f = () => {throw e};
} finally {
assert.throws(f, regExp);
}
}
我想使用本机 assert
模块中的 assert.throws
检查异步函数是否抛出异常。
我试过
const test = async () => await aPromise();
assert.throws(test); // AssertionError: Missing expected exception..
它(显然?)不起作用,因为该函数在 Promise 解析之前就退出了。 然而我发现 this question 使用回调可以达到同样的效果。
有什么建议吗?
(我正在使用 Babel 转译为 Node.js 本机生成器。)
节点 10 和更新的节点
从 Node.js v10.0 开始,assert.rejects
就是这样做的。
旧版本的节点
async
函数从不抛出 - 它们 return 承诺可能会被拒绝。
您不能对它们使用 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);
在异步测试用例中。
基于
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.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/
});
});
由于问题还在关注中,我想总结一下两个最好的解决方案,特别强调一下新的标准方法。
节点 v10+
断言库中有一个专用方法,assert.rejects
。
对于旧版本的 Node
来自
import assert from 'assert';
async function assertThrowsAsync(fn, regExp) {
let f = () => {};
try {
await fn();
} catch(e) {
f = () => {throw e};
} finally {
assert.throws(f, regExp);
}
}