Jest测试创建空Blob对象调用text()方法报错该如何处理?
问题根因
Jest默认运行在Node.js环境下,Node内置的Blob实现和浏览器端Blob API存在差异:低于15.x的Node版本没有原生Blob支持,高版本Node的Blob实例也没有提供text()、arrayBuffer()等浏览器端标准方法。而之前的Karma测试运行在真实浏览器环境,存在完整的Blob API实现,所以不会出现报错。另外你原有测试用例没有处理异步逻辑,Blob.text()本身返回Promise,直接同步调用expect本身也属于不规范写法。
可选择的解决方案
方案1:配置Jest模拟浏览器环境并添加Blob polyfill
这是改动最小、最贴近真实运行场景的方案
- 安装所需依赖:
npm install jest-environment-jsdom blob-polyfill --save-dev
- 修改Jest配置文件(jest.config.js或jest.config.ts):
module.exports = { // 改为jsdom模拟浏览器环境 testEnvironment: 'jsdom', // 配置全局引入polyfill的文件 setupFilesAfterEnv: ['<rootDir>/src/setup.jest.ts'] }
- 在setup.jest.ts中全局引入Blob polyfill:
import 'blob-polyfill';
- 修正测试用例的异步逻辑:
it('should return properties for update', async () => { const blob: Blob = appService._buildBlobForProperties(app); // 加await读取Promise返回的文本内容 expect(await blob.text()).toBe(await updateBlob.text()); });
方案2:用兼容的FileReader API读取Blob内容
如果不想引入额外polyfill,可以用FileReader实现Blob内容读取,兼容Node和浏览器环境:
it('should return properties for update', async () => { const blob: Blob = appService._buildBlobForProperties(app); // 封装通用的Blob文本读取方法 const readBlobText = (blob: Blob): Promise<string> => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as string); reader.onerror = reject; reader.readAsText(blob); }); }; const resultContent = await readBlobText(blob); const expectedContent = await readBlobText(updateBlob); expect(resultContent).toBe(expectedContent); });
方案3:Mock Blob构造函数直接验证入参
如果不需要验证Blob实例本身的行为,只需要验证函数逻辑是否正确,可以直接Mock Blob构造函数,检查传入的参数是否符合预期:
it('should return properties for update', () => { // 备份原生Blob构造函数 const originalBlob = global.Blob; // 自定义Mock Blob构造函数 const mockBlob = jest.fn().mockReturnValue({}); global.Blob = mockBlob as unknown as typeof Blob; // 调用目标方法 appService._buildBlobForProperties(app); // 验证Blob构造函数的入参是否符合预期 expect(mockBlob).toHaveBeenCalledWith( [JSON.stringify({ name: app.name, description: app.description })], { type: 'application/json' } ); // 恢复原生Blob构造函数 global.Blob = originalBlob; });
内容的提问来源于stack exchange,提问作者Jason Rogers
相关产品推荐
相关产品推荐

