mock Canvas上下文专为单元测试和离线开发设计,用于验证fillRect、strokeText等绘图方法调用逻辑,无需真实渲染;只需按需实现实际调用的方法并记录参数,配合jest.fn()断言行为,优先抽离纯函数如getBarPositions单独测试以提升可测性。

直接 mock Canvas 上下文不是为了替代真实图表库,而是为单元测试或离线开发做准备——比如验证绘图逻辑是否正确调用 fillRect、strokeText 等方法,而无需真实渲染。
创建轻量级 Canvas 2D 上下文模拟对象
不需要引入完整库,只需按需实现你代码中实际调用的方法。例如:
- fillStyle、strokeStyle:设为字符串属性,支持读写
- fillRect(x, y, w, h):记录调用参数到数组,便于断言
- strokeText(text, x, y):同样存入日志,不真画字
-
measureText(text):返回带
width属性的模拟对象(如{ width: text.length * 10 }) - clearRect():可空实现,或标记“已清空”状态
在测试中注入 mock 上下文
你的绘图函数通常接收一个 ctx 参数。测试时传入 mock 对象即可:
const mockCtx = {
fillStyle: '',
strokeStyle: '',
fillRect: jest.fn(),
strokeRect: jest.fn(),
strokeText: jest.fn(),
measureText: jest.fn().mockImplementation(t => ({ width: t.length * 12 })),
save: jest.fn(),
restore: jest.fn(),
translate: jest.fn(),
scale: jest.fn()
};然后调用你的绘图函数:drawBarChart(mockCtx, data),再用 expect(mockCtx.fillRect).toHaveBeenCalledWith(10, 20, 40, 80) 验证行为。
立即学习“Java免费学习笔记(深入)”;
注意真实 canvas 元素的兼容性
某些库(如 F2、Chart.js)内部会检查 ctx instanceof CanvasRenderingContext2D。若需绕过该检测,可用如下方式构造更接近真实的 mock:
- 用
Object.setPrototypeOf(mockCtx, CanvasRenderingContext2D.prototype)挂载原型链 - 或使用
jest.mock('canvas')(Node 环境配合 node-canvas)生成真实上下文 - 浏览器环境推荐用
document.createElement('canvas').getContext('2d')获取原生实例,再用jest.spyOn替换关键方法
避免过度 mock,优先隔离绘图逻辑
真正健壮的做法是把坐标计算、数据映射等纯函数抽离出来单独测试;只对绘制指令做浅层 mock。这样既保证逻辑可测,又不依赖 Canvas 实现细节。例如:
- 函数
getBarPositions(data, config)返回[{x, y, width, height}]—— 可直接断言输出 - 函数
renderBars(ctx, positions)只负责调用ctx.fillRect—— mock ctx 即可验证调用次数和参数


















