You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:05:20