You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:24:03