如何在Jest中Mock React自定义Hook里的DOMMatrix实例?
在Jest中Mock DOMMatrix的可行方案
核心思路
Jest运行环境没有浏览器的DOMMatrix全局API,所以需要手动在全局对象上挂载Mock类/函数,同时配套MockgetComputedStyle(因为你的代码依赖它获取transform值),确保Hook能正常创建实例并修改属性。
具体实现
1. 基础Mock(固定初始值)
在测试文件的beforeAll或beforeEach中定义并挂载Mock:
// 定义MockDOMMatrix类,模拟真实实例的属性 class MockDOMMatrix { constructor() { // 预设初始的e、f值,可根据测试需求调整 this.e = 0; this.f = 0; } } beforeAll(() => { // 将Mock类挂载到全局,覆盖不存在的DOMMatrix global.DOMMatrix = MockDOMMatrix; // Mock getComputedStyle,返回符合格式的transform字符串(Mock类可以忽略参数,这里仅保持代码逻辑一致) global.getComputedStyle = jest.fn(() => ({ transform: 'matrix(1, 0, 0, 1, 0, 0)' })); });
2. 灵活Mock(动态调整初始值)
如果需要在不同测试用例中使用不同的初始e、f值,用jest.fn替代类,方便动态返回实例:
beforeEach(() => { // 重置Mock,保证每个测试用例独立 global.DOMMatrix = jest.fn(() => ({ e: 10, // 当前测试用例的初始e值 f: 20 // 当前测试用例的初始f值 })); global.getComputedStyle = jest.fn(() => ({ transform: '' })); });
3. 测试验证逻辑
测试Hook中修改matrix.e和matrix.f的逻辑:
test('should update matrix e and f based on movement', () => { // 模拟鼠标移动事件对象 const mockEvent = { movementX: 5, movementY: -3 }; // 调用你的自定义Hook或相关逻辑(这里假设你的Hook接收element和event作为参数) // 示例:useYourCustomHook(mockElement, mockEvent); // 获取DOMMatrix创建的实例 const matrixInstance = global.DOMMatrix.mock.results[0].value; // 断言属性修改正确 expect(matrixInstance.e).toBe(10 + 5); // 初始值10 + movementX 5 expect(matrixInstance.f).toBe(20 + (-3)); // 初始值20 + movementY -3 });
为什么之前的方法无效?
jest.spyOn失败:Jest环境中不存在DOMMatrix全局属性,spyOn无法监听一个不存在的对象属性。jest.mock不适用:DOMMatrix是浏览器全局API,不是第三方模块,无法通过jest.mock的模块路径方式Mock,必须直接修改全局对象。- 创建Mock类但未挂载:仅定义Mock类但未赋值给
global.DOMMatrix,代码执行时仍找不到DOMMatrix,导致报错。
内容的提问来源于stack exchange,提问作者msqar
相关产品推荐
相关产品推荐

