如何在Jest单元测试中对node-canvas依赖进行Mock?
解决方案
错误根因
现有代码的核心问题有两个:
- jest.mock的参数填写错误:你实际导入的模块是
canvas,但你写的mock目标是不存在的模块nodeCanvas,mock规则未生效,导致测试加载了真实的node-canvas包,触发其二进制依赖相关的报错。 - 仅空mock模块没有模拟必要的API,即使mock模块名正确,
qr-code-styling调用node-canvas的相关方法时也会抛出未定义错误。
可行修复方案
方案1:mock node-canvas模块(适合需要验证canvas调用逻辑的场景)
修正mock的模块名,同时补充qr-code-styling运行所需的最小API模拟,示例代码如下:
// 注意mock的模块名和你import的模块名完全一致,为'canvas' jest.mock('canvas', () => ({ createCanvas: jest.fn(() => ({ getContext: jest.fn(() => ({ fillStyle: '', fillRect: jest.fn(), drawImage: jest.fn(), // 可根据实际调用的API按需补充其他2D上下文方法 })), toBuffer: jest.fn().mockReturnValue(Buffer.from('mock qr content')), toDataURL: jest.fn().mockReturnValue('data:image/png;base64,mockBase64'), })), loadImage: jest.fn().mockResolvedValue(Buffer.from('')), // 其他`qr-code-styling`用到的canvas导出方法可按需补充 })) // 后续正常导入nodeCanvas和业务代码即可 import * as nodeCanvas from 'canvas';
方案2:直接mock qr-code-styling(适合只需验证业务逻辑、不需要验证二维码生成细节的场景)
如果不需要测试二维码生成的具体逻辑,直接mock上层依赖qr-code-styling更简单,无需处理canvas的模拟逻辑:
jest.mock('qr-code-styling', () => jest.fn().mockImplementation(() => ({ // 补充你业务代码中调用的所有QRCodeStyling实例方法 toDataURL: jest.fn().mockResolvedValue('data:image/png;base64,mockQrBase64'), getRawData: jest.fn().mockResolvedValue(Buffer.from('mock qr buffer')), append: jest.fn(), })))
内容的提问来源于stack exchange,提问作者user2194639
相关产品推荐
相关产品推荐

