Jest报错Cannot log after tests are done,如何修改测试获取sharp图片resize成功结果
问题原因
你当前的resize函数的Promise逻辑存在时序错误:在启动文件流管道后就立刻调用resolve('slow'),没有等待图片resize、文件写入的完整异步流程执行完成。测试用例await拿到返回值后就默认测试执行完毕,后续transform的info事件、writeStream的close事件触发时,jest已经结束了当前测试生命周期,因此会抛出「测试结束后无法进行日志打印」的错误。
修复方案
方案1(推荐):修正resize函数的Promise逻辑
调整Promise的resolve/reject时机,等待所有异步流程完成后再返回结果:
export default function resize( inputPath: string, outputPath: string, format: string, width: number | null, height: number | null ): Promise<string> { return new Promise((resolve, reject) => { setTimeout(() => { const readStream: fs.ReadStream = fs.createReadStream(inputPath); const writeStream: fs.WriteStream = fs.createWriteStream(outputPath); writeStream.on('error', (err) => { console.log('Error'); reject(err); }); writeStream.on('close', () => { console.log('Successfully saved'); // 所有流程完成后再resolve resolve('slow'); }); let transform: sharp.Sharp = sharp(); if (format === 'jpeg' || format === 'png') { transform = transform.toFormat(format); } transform = transform .resize(width, height) .on('info', (fileInfo) => console.log('Successfully resized')) .on('error', (err) => reject(err)); readStream.pipe(transform).pipe(writeStream); }, 1000); }); }
修改后原测试用例无需调整,await会自动等待所有流程执行完成,就能正常看到所有日志输出。
方案2:仅修改测试用例(不调整原函数)
如果你暂时不想修改原函数实现,可以在测试用例中手动等待流处理完成,确保测试在所有异步逻辑执行完成后再结束:
import * as fs from 'fs/promises'; describe('resize', () => { test('resize the images', async () => { const outputPath = 'src/images/thumbnails/palmtunnel_500_400.jpg'; // 先清理旧的输出文件 try { await fs.unlink(outputPath); } catch {} const s: string = await resize( 'src/images/full/palmtunnel.jpg', outputPath, 'jpeg', 500, 400 ); console.log(s); // 等待输出文件生成,确认流处理完成 while (true) { try { await fs.access(outputPath); break; } catch { await new Promise(resolve => setTimeout(resolve, 200)); } } // 额外预留100ms等待事件回调执行 await new Promise(resolve => setTimeout(resolve, 100)); }); });
注意:方案2属于临时兼容方案,实际开发更推荐优先修正原函数的异步逻辑,避免后续其他地方调用时出现同样的时序问题。
内容的提问来源于stack exchange,提问作者Arefe
相关产品推荐
相关产品推荐

