ネイティブassert
モジュールの assert.throws
を使用して非同期関数がスローするかどうかを確認したいと思います。私が試した
const test = async () => await aPromise();
assert.throws(test); // AssertionError: Missing expected exception..
Promiseが解決される前に関数が終了するため、(obvioulsy?)は機能しません。それでも私はこれを発見しました 質問 コールバックを使用して同じことが達成されます。
なにか提案を?
(私はBabelを使用してNode.jsネイティブジェネレーターに変換しています)
質問はまだ注目されているので、特に新しい標準的な方法を強調するために、2つの最良の解決策を要約したいと思います。
アサートライブラリには専用のメソッド 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);
}
}
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);
非同期テストケース
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/);
});
答えは上手くいきましたが、私は今日この問題に出くわし、もう少し簡単な解決策を考え出しました。
// 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'))
}
Node.jsバージョン10の新機能であるassert.rejects()
を使用します。
高レベルでは、assert.throwsの代わりに、assert.rejectsのようなものが必要です。うまくいけば、これを取得して実行できます。
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/
});
});