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

如何使用Jest模拟块级作用域变量?测试含块级变量的方法

Jest测试含块级作用域变量代码的正确实践

不需要为了测试修改内部变量的作用域——测试的核心是验证函数的输入输出、依赖调用和副作用,而非直接访问内部块级变量。针对你提供的downloadAttachment方法,我们可以通过模拟依赖、断言关键行为来覆盖包括for循环在内的所有逻辑。

先贴出你的示例代码(附中文逻辑注释):

downloadAttachment(attachment: Attachment) {
    // 解码base64格式的附件内容
    const byteCharacters = window.atob(attachment.attachment);
    const byteNumbers = new Array(byteCharacters.length);
    // 遍历字符,将每个字符转为对应ASCII码值
    for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    // 将码值数组转为Uint8Array
    const byteArray = new Uint8Array(byteNumbers);
    // 生成JPG格式的Blob对象
    const blob = new Blob([byteArray], { type: 'image/jpeg' });
    // 触发文件下载
    saveAs(blob, 'attachment');
}

具体测试步骤

  • 模拟全局依赖:用Jest的mock函数替换window.atob和saveAs,方便控制返回值、断言调用行为。
  • 构造可控输入:生成包含已知base64字符串的Attachment对象,确保能预知解码后的字符内容。
  • 断言关键逻辑:通过验证最终生成的Blob内容、saveAs的调用参数,间接确认for循环的处理逻辑正确。

完整测试代码示例

import { saveAs } from 'file-saver';
import { downloadAttachment } from './your-module-path';

// 模拟saveAs函数
jest.mock('file-saver', () => ({
    saveAs: jest.fn()
}));

describe('downloadAttachment', () => {
    beforeEach(() => {
        // 每次测试前重置mock状态
        jest.clearAllMocks();
        // 模拟window.atob返回固定字符串,方便后续验证编码转换
        window.atob = jest.fn(() => "ABC");
    });

    it('应正确解码base64并触发下载', () => {
        // 构造测试用Attachment对象,"ABC"对应的base64编码为QUJD
        const testAttachment = {
            attachment: 'QUJD'
        };

        // 调用目标函数
        downloadAttachment(testAttachment as Attachment);

        // 验证atob是否被传入正确的base64参数
        expect(window.atob).toHaveBeenCalledWith('QUJD');

        // 验证saveAs的调用参数
        const mockSaveAs = saveAs as jest.Mock;
        expect(mockSaveAs).toHaveBeenCalledWith(expect.any(Blob), 'attachment');
        
        // 读取Blob内容,验证for循环的编码转换逻辑是否正确
        const blob = mockSaveAs.mock.calls[0][0] as Blob;
        return new Promise((resolve) => {
            const reader = new FileReader();
            reader.onload = () => {
                const uint8Array = new Uint8Array(reader.result as ArrayBuffer);
                // "ABC"对应的ASCII码为65、66、67
                expect(uint8Array).toEqual(new Uint8Array([65, 66, 67]));
                resolve();
            };
            reader.readAsArrayBuffer(blob);
        });
    });

    it('应正确处理空内容的附件', () => {
        window.atob = jest.fn(() => "");
        const testAttachment = { attachment: '' };
        
        downloadAttachment(testAttachment as Attachment);
        
        const mockSaveAs = saveAs as jest.Mock;
        const blob = mockSaveAs.mock.calls[0][0] as Blob;
        expect(blob.size).toBe(0);
    });
});

核心思路说明

  • 无需访问byteCharacters、byteNumbers等内部变量,通过控制输入、验证最终输出和副作用即可覆盖所有逻辑,包括for循环的遍历转换。
  • 模拟依赖能隔离外部环境影响,让测试更稳定、执行更快。
  • 若要测试边界场景(如空字符串、特殊字符),只需构造对应的base64输入,复用上述验证逻辑即可。

内容的提问来源于stack exchange,提问作者fadingbeat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:36:17