Angular Jest单元测试中如何Mock第三方LeaderLine库
解决Angular Jest测试中Mock LeaderLine库的问题
错误原因
你遇到的TypeError: Cannot read properties of undefined (reading 'prototype'),是因为Jest未正确Mock leader-line-new模块,当组件尝试实例化LeaderLine时,找不到有效的构造函数引用,进而触发原型访问错误。
解决方案
1. Mock整个leader-line-new模块
在组件测试文件顶部添加全局Mock,模拟构造函数和所需静态方法:
// 模拟leader-line-new模块 jest.mock('leader-line-new', () => { // 创建Mock构造函数 const MockLeaderLine = jest.fn(); // 模拟静态方法captionLabel,返回任意对象即可(无需真实DOM行为) MockLeaderLine.captionLabel = jest.fn(() => ({})); return MockLeaderLine; });
2. 初始化组件的DOM元素引用
由于LeaderLine构造需要两个DOM元素的nativeElement,需在测试前模拟这些@ViewChild引用:
beforeEach(() => { fixture = TestBed.createComponent(YourComponent); component = fixture.componentInstance; // 模拟ViewChild的nativeElement(Jest环境无真实DOM) component.transformDiv = { nativeElement: document.createElement('div') } as any; component.validateXmlPanel = { nativeElement: document.createElement('div') } as any; fixture.detectChanges(); });
3. 更新测试用例验证逻辑
修改测试用例,确保变量引用被正确设置,同时可验证Mock的构造函数和静态方法是否被调用:
it('[constructRoutingLines] - should create routing lines between components (validate xml = true)', () => { const componentSpy = jest.spyOn(component, 'removeConnectionsFromDOM').mockImplementation(); const spinnerSpy = jest.spyOn(spinnerService, 'hide'); component.constructRoutingLines(); // 验证原有逻辑 expect(componentSpy).toHaveBeenCalled(); expect(spinnerSpy).toHaveBeenCalled(); // 验证routingToValidation变量已被赋值 expect(component.routingToValidation).toBeDefined(); // 验证LeaderLine构造函数被正确调用 const LeaderLine = require('leader-line-new'); expect(LeaderLine).toHaveBeenCalledWith( component.transformDiv.nativeElement, component.validateXmlPanel.nativeElement, expect.objectContaining({ endPlug: 'arrow3', color: 'darkgray', middleLabel: expect.any(Object) }) ); // 验证静态方法captionLabel被调用 expect(LeaderLine.captionLabel).toHaveBeenCalledWith( 'Transformed Data Routing To', expect.objectContaining({ color: 'black', fontSize: '14px' }) ); });
关键说明
- 无需模拟
LeaderLine的真实DOM行为,只需确保组件能正常完成实例化并赋值变量即可。 - 通过
jest.mock全局Mock模块,确保所有对LeaderLine的引用都指向Mock构造函数。 - 模拟
nativeElement是为了避免构造函数因找不到DOM元素而报错。
内容的提问来源于stack exchange,提问作者millerbill3
相关产品推荐
相关产品推荐

