Angular中使用Jest spyOn报错:Cannot spyOn on a primitive value; undefined given
报错原因及修复方案
1. 解决"Cannot spyOn on a primitive value; undefined given"报错
这个报错说明component.cpfMask为undefined,核心原因是组件初始化不完整:
- 组件依赖
ReactiveFormsModule(用到了FormGroup/FormControl),但测试模块未导入,导致组件初始化失败,实例方法无法正常挂载。 - 组件的
cpfValid、cpfForm等关键属性未初始化,破坏了实例完整性。
修改测试模块配置,补充必要依赖:
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ TeamsComponent ], imports: [ReactiveFormsModule] // 导入表单模块 }) .compileComponents(); }));
在组件初始化前手动补全依赖属性:
beforeEach(() => { fixture = TestBed.createComponent(TeamsComponent); component = fixture.componentInstance; // 初始化CPF验证正则(根据实际业务填写) component.cpfValid = '^\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}$'; // 初始化表单控件 component.cpfForm = new FormGroup({ cpf: new FormControl('') }); fixture.detectChanges(); });
2. 优化测试用例逻辑
原测试用例存在参数错误、逻辑不符函数实际行为的问题,针对性调整如下:
测试1:验证cpfMask被调用
原测试调用ngOnInit()但该生命周期钩子并未触发cpfMask,需模拟函数触发场景:
it('should call cpfMask when handling input', () => { const spy = jest.spyOn(component, 'cpfMask').mockImplementation(() => {}); // 创建符合函数参数要求的模拟事件对象 const mockEvent = { target: { value: '11111111111' } }; // 手动触发函数 component.cpfMask(mockEvent); expect(spy).toHaveBeenCalled(); });
测试2:验证CPF格式化功能
cpfMask无返回值,它直接修改event.target.value,需断言该值的变化:
it('should format CPF correctly', () => { const mockEvent = { target: { value: '11111111111' } }; component.cpfMask(mockEvent); expect(mockEvent.target.value).toBe('111.111.111-11'); });
测试3:验证无效输入被截断
当输入不符合正则规则时,函数会截断最后一位,测试该逻辑:
it('should truncate invalid CPF input', () => { const mockEvent = { target: { value: '111.111.111-11a' } }; component.cpfMask(mockEvent); expect(mockEvent.target.value).toBe('111.111.111-11'); });
3. 组件代码优化(可选)
为了降低测试复杂度,可将格式化逻辑与事件处理分离:
// 单独抽离格式化函数,方便独立测试 public formatCPF(value: string): string { return value.replace(/^(\d{3})(\d{3})(\d{3})(\d{2})/, "$1.$2.$3-$4"); } public cpfMask(event: any) { let newValue = event.target.value; const regExp = new RegExp(this.cpfValid); this.cpfControl = this.cpfForm.get("cpf"); const pattern = this.formatCPF(newValue); event.target.value = pattern; if (!regExp.test(pattern)) { event.target.value = newValue.slice(0, -1); } }
内容的提问来源于stack exchange,提问作者josecarlos
相关产品推荐
相关产品推荐

