摩卡:如何断言承诺拒绝?
Mocha: how to assert a promise rejection?
我试图让 Mocha 显示错误并在我的节点代码上断言一个被拒绝的承诺 - ...而不是显示 UnhandledPromiseRejectionWarning
异常导致我的异步函数是拒绝了。
我已经搜索并尝试了很多关于在 Mocha 中处理此警告和承诺拒绝的建议,但其中 none 对我有用。这似乎是一个反复出现的话题,也是一个让很多人非常困惑的话题。
我正在尝试通过:
使用 lambda 函数
不使用 done
使用简单的断言(我不喜欢 expect
和 should
)
通过 try/catch 处理错误(我不喜欢链式 .then
和 .catch
;如果使用 .then(res,err)
则更不喜欢它)
类似于:
it('should give an error',
async ()=> {
try{
await generateException()
assert(true)
} catch(err) {
console.err(err)
assert ??? // how to 'assert' a promise rejection?
}
}
)
如果不可避免地使用任何我不太喜欢的东西,那很好。但是,什么是更接近我想要的解决方案?
此外,我不明白为什么被拒绝的承诺不会像我期望的那样在 try/catch 中被捕获,因为这正是使用 await
的意义所在(使异步代码像同步一样工作。
这对我有用。出于示例目的,使用 chai 进行断言。
const chai = require('chai');
const expect = chai.expect;
describe('test', function () {
function generateException() {
throw new Error('test error');
}
it('should give an error', async ()=> {
try {
await generateException();
expect(true).to.be.false;
} catch(err) {
console.log(err.message);
expect(err.message).to.equal('test error');
}
})
})
Promise.reject()
与 throw new Error()
的使用方式似乎有所不同。当函数 generateException
抛出错误时,您的测试工作。
但是,如果它是 Promise.reject()
,它永远不会到达 catch 块。
如果您执行类似 let result = await generateException();
的操作,如果 geenerateException
函数使用 promise reject,您会发现这是您预期的错误。
如果您愿意,您可以将 promise 与 await 链接起来。
function generateException() {
return new Promise(reject => {
return reject(new Error('Promise Rejected');
})
it('should give an error', async ()=> {
await generateException().catch(error => {
expect(error.message).to.equal('Promise Rejected');
})
});
阅读 this article on async code 的部分内容可能会有所帮助。
使用 mocha 单元测试
断言节点模块:
这是我的建议:
const assert = require('assert');
const PromiseFail = async (proms) => await assertPromise(proms, false);
const PromiseSucced = async (proms) => await assertPromise(proms);
const assertPromise = async (prom, succed = true) => {
succed = succed ? true : false;
try {
prom = Array.isArray(prom) ? prom : [prom];
await Promise.all(prom);
assert.strictEqual(true, succed);
}
catch (ex) { assert.notStrictEqual(true, succed, ex); }
}
测试中:
describe('unit test', () => {
it('test 1', async () => {
await PromiseSucced(Promise.resolve(1))
await PromiseSucced([Promise.resolve(2), Promise.resolve(3)])
const promise4 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'foo');
});
await PromiseFail(promise4)
});
})
使用 assert 库
测试 promise 拒绝非常简单
import { strict as assert } from 'assert'
it('should give an error', async function () {
await assert.rejects(generateException())
})
如果您需要打印错误,您可以这样做
import { strict as assert } from 'assert'
it('should give an error', async function () {
await assert.rejects(generateException()).catch((err) => {
console.err(err)
throw err
}
})
我试图让 Mocha 显示错误并在我的节点代码上断言一个被拒绝的承诺 - ...而不是显示 UnhandledPromiseRejectionWarning
异常导致我的异步函数是拒绝了。
我已经搜索并尝试了很多关于在 Mocha 中处理此警告和承诺拒绝的建议,但其中 none 对我有用。这似乎是一个反复出现的话题,也是一个让很多人非常困惑的话题。
我正在尝试通过:
使用 lambda 函数
不使用
done
使用简单的断言(我不喜欢
expect
和should
)通过 try/catch 处理错误(我不喜欢链式
.then
和.catch
;如果使用.then(res,err)
则更不喜欢它)
类似于:
it('should give an error',
async ()=> {
try{
await generateException()
assert(true)
} catch(err) {
console.err(err)
assert ??? // how to 'assert' a promise rejection?
}
}
)
如果不可避免地使用任何我不太喜欢的东西,那很好。但是,什么是更接近我想要的解决方案?
此外,我不明白为什么被拒绝的承诺不会像我期望的那样在 try/catch 中被捕获,因为这正是使用 await
的意义所在(使异步代码像同步一样工作。
这对我有用。出于示例目的,使用 chai 进行断言。
const chai = require('chai');
const expect = chai.expect;
describe('test', function () {
function generateException() {
throw new Error('test error');
}
it('should give an error', async ()=> {
try {
await generateException();
expect(true).to.be.false;
} catch(err) {
console.log(err.message);
expect(err.message).to.equal('test error');
}
})
})
Promise.reject()
与 throw new Error()
的使用方式似乎有所不同。当函数 generateException
抛出错误时,您的测试工作。
但是,如果它是 Promise.reject()
,它永远不会到达 catch 块。
如果您执行类似 let result = await generateException();
的操作,如果 geenerateException
函数使用 promise reject,您会发现这是您预期的错误。
如果您愿意,您可以将 promise 与 await 链接起来。
function generateException() {
return new Promise(reject => {
return reject(new Error('Promise Rejected');
})
it('should give an error', async ()=> {
await generateException().catch(error => {
expect(error.message).to.equal('Promise Rejected');
})
});
阅读 this article on async code 的部分内容可能会有所帮助。
使用 mocha 单元测试
断言节点模块: 这是我的建议:
const assert = require('assert');
const PromiseFail = async (proms) => await assertPromise(proms, false);
const PromiseSucced = async (proms) => await assertPromise(proms);
const assertPromise = async (prom, succed = true) => {
succed = succed ? true : false;
try {
prom = Array.isArray(prom) ? prom : [prom];
await Promise.all(prom);
assert.strictEqual(true, succed);
}
catch (ex) { assert.notStrictEqual(true, succed, ex); }
}
测试中:
describe('unit test', () => {
it('test 1', async () => {
await PromiseSucced(Promise.resolve(1))
await PromiseSucced([Promise.resolve(2), Promise.resolve(3)])
const promise4 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'foo');
});
await PromiseFail(promise4)
});
})
使用 assert 库
测试 promise 拒绝非常简单import { strict as assert } from 'assert'
it('should give an error', async function () {
await assert.rejects(generateException())
})
如果您需要打印错误,您可以这样做
import { strict as assert } from 'assert'
it('should give an error', async function () {
await assert.rejects(generateException()).catch((err) => {
console.err(err)
throw err
}
})