如何使用Mocha测试多个Promise?
问题:测试多个Promise时Mocha报错(done()被多次调用+方法冲突)
我正在测试request-image-size库返回的Promise:传入图片URL后会得到尺寸响应,打不开图片则返回错误。
我的test.js测试用例如下:
describe('Test images', () => { it('Should test all image sizes',async (done) => { const imagesResonses = await getAllImageResponses(imagesURLs) // 打印imageResponses会得到一个Promise数组,其中两个应被拒绝并抛出错误 // [ // Promise { <pending> }, // Promise { <pending> }, // Promise { <pending> }, // Promise { <pending> }, // Promise { <pending> }, // Promise { <pending> } // ] imagesResonses.map((image) => image.then((res) => { console.log(res) assert(res.height > 0, 'height must be greater than zero'); done() }).catch((err) => { console.log(err) done(err) })) })
测试时出现以下错误:
done() called multiple times in test <Test links and images S should test all image sizes> of file C:path/test.js; in addition, don e() received error: Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
需求:对每个Promise执行断言,Promise被拒绝时记录错误。
错误原因分析
- 方法冲突:你同时使用了
async函数(本身会返回Promise)和done回调,Mocha不允许同时用这两种方式标记测试结束,二选一即可。 - done()被多次调用:你在每个Promise的
then/catch回调里都调用了done,数组有多少个Promise就会调用多少次done,但Mocha要求每个测试只能调用一次done。
解决方案
方案1:用Promise.allSettled逐个处理成功/失败结果
适合需要分别处理每个Promise的成功和失败场景(比如允许部分图片加载失败,只记录错误):
describe('Test images', () => { it('Should test all image sizes', async () => { // 注意:这里不需要提前await,直接获取Promise数组即可 const imagePromises = getAllImageResponses(imagesURLs); // 等待所有Promise完成(无论成功/失败) const results = await Promise.allSettled(imagePromises); results.forEach((result, index) => { if (result.status === 'fulfilled') { const res = result.value; console.log(`图片${index+1}成功:`, res); assert(res.height > 0, `图片${index+1}高度必须大于0`); } else { const err = result.reason; console.log(`图片${index+1}加载失败:`, err); // 若要求所有图片必须成功,可在此抛出错误终止测试 // throw new Error(`图片${index+1}加载失败:${err.message}`); } }); }) })
方案2:用Promise.all要求所有Promise必须成功
如果所有图片都必须成功获取尺寸,用Promise.all更简洁(只要有一个Promise失败,测试直接终止):
describe('Test images', () => { it('Should test all image sizes', async () => { // 等待所有Promise成功,失败则直接抛出错误 const imageResults = await Promise.all(getAllImageResponses(imagesURLs)); imageResults.forEach((res, index) => { console.log(`图片${index+1}结果:`, res); assert(res.height > 0, `图片${index+1}高度必须大于0`); }); }) })
关键修改点
- 移除
async函数的done参数,async函数返回的Promise会被Mocha自动识别,无需手动调用done。 - 用
Promise.all/Promise.allSettled统一处理Promise数组,避免多次触发测试结束逻辑。 - 遍历结果数组做断言,不要在单个Promise的回调里直接结束测试。
内容的提问来源于stack exchange,提问作者heyooo12
相关产品推荐
相关产品推荐

