Angular单元测试报错:fControl.get is not a function求解答
问题:单元测试调用changeFunctionalityStatus时报错
fControl.get is not a function 尝试为changeFunctionalityStatus()编写单元测试时遇到报错:fControl.get is not a function,目前被该问题卡住,希望有人帮忙分析问题原因。
相关代码
组件方法代码
changeFunctionalityStatus(fControl: FormControl, screen) { if (this.isConsult) return; const isFuncActivated = fControl.get('isFunctionalityActivatedController').value; if (fControl.value.functionalityCodeController == "CONSULT_PROJECT" || fControl.value.functionalityCodeController == "CONSULT_BUSINESS_OFFER" || fControl.value.functionalityCodeController == "CONSULT_PROJECT_CONTRACT" || fControl.value.functionalityCodeController == "CONSULT_BILLING_LIST" || fControl.value.functionalityCodeController == "CONSULT_PROJECT_INVOICES" || fControl.value.functionalityCodeController == "CONSULT_CONTRACT" || fControl.value.functionalityCodeController == "CONSULT_MILESTONE") { this.removeFunctionalitiesByScreen(screen); } if (isFuncActivated) { this.removeFunctionality(fControl); } else { this.addFunctionality(fControl); } this.checkAndSetScreenAccessController(screen); }
测试代码(spec.ts)
it('changeFunctionalityStatus', () => { spyOn(component, 'changeFunctionalityStatus').and.callThrough(); component.changeFunctionalityStatus({} as FormControl,"mockscreen"); expect(component.changeFunctionalityStatus).toHaveBeenCalled(); });
问题原因
你在测试中传入的{} as FormControl只是一个空对象——虽然TypeScript的类型断言能让编译通过,但运行时这个对象并没有FormControl(或实际用到的FormGroup)的get方法,调用fControl.get()时自然会报错。
另外要注意:组件方法里调用的fControl.get()是FormGroup的API,FormControl本身并没有get方法(FormControl是单个表单控件,只能直接访问value),所以组件的参数类型定义大概率有误,应该将fControl: FormControl改为fControl: FormGroup。
解决方法
方法1:用Angular FormBuilder创建真实表单组
通过FormBuilder构建符合要求的FormGroup,模拟真实表单控件结构:
import { FormBuilder, FormGroup } from '@angular/forms'; // 在测试套件的beforeEach中注入FormBuilder let fb: FormBuilder; beforeEach(() => { TestBed.configureTestingModule({ providers: [FormBuilder] }); fb = TestBed.inject(FormBuilder); // 初始化组件等其他逻辑 }); it('changeFunctionalityStatus', () => { spyOn(component, 'changeFunctionalityStatus').and.callThrough(); // 创建包含所需控件的模拟表单组 const mockFormGroup = fb.group({ isFunctionalityActivatedController: [false], functionalityCodeController: ['CONSULT_PROJECT'] // 可根据测试场景修改值 }); // 如果组件参数类型还没改成FormGroup,用类型断言过渡 component.changeFunctionalityStatus(mockFormGroup as unknown as FormControl, "mockscreen"); expect(component.changeFunctionalityStatus).toHaveBeenCalled(); });
方法2:手动Mock表单对象
如果不想依赖真实FormBuilder,可手动创建包含get方法和value属性的对象,模拟表单组行为:
it('changeFunctionalityStatus', () => { spyOn(component, 'changeFunctionalityStatus').and.callThrough(); const mockFControl = { get: (controlName: string) => ({ value: false // 模拟isFunctionalityActivatedController的值 }), value: { functionalityCodeController: 'CONSULT_PROJECT' // 模拟功能码的值 } } as FormControl; component.changeFunctionalityStatus(mockFControl, "mockscreen"); expect(component.changeFunctionalityStatus).toHaveBeenCalled(); });
内容的提问来源于stack exchange,提问作者web_in
相关产品推荐
相关产品推荐

