Angular单元测试:在describe调用时获取fixture与component值
解决Angular单元测试中describe阶段无法获取component.formGroup的问题
你遇到的TypeError: Cannot read property 'formGroup' of undefined是Angular测试生命周期的典型问题——describe是在测试套件的定义阶段执行的,此时你的beforeEach还没运行,component实例根本还没被创建,所以直接传component.formGroup肯定拿不到值。
核心思路:延迟获取formGroup的时机
我们需要把formGroup的获取延迟到测试真正执行的阶段(也就是it语句运行时),此时beforeEach已经完成了component的初始化。具体可以通过传递一个返回formGroup的函数来实现,而不是直接传递formGroup的值。
步骤1:修改通用测试函数
把原来接收formGroup: any的参数改成接收一个返回formGroup的函数getFormGroup: () => any,在it内部再调用这个函数拿到实例化后的formGroup:
export const componentTestFn = (getFormGroup: () => any, fields: Fields[], configurationOptions?) => () => { describe('On required fields', () => { beforeEach(() => { if (configurationOptions) { TestBed.configureTestingModule(configurationOptions) .compileComponents(); } }); fields.forEach(element => { describe(element.name, () => { it('should be a required field', () => { // 此时beforeEach已执行,component实例存在,能正确拿到formGroup const formGroup = getFormGroup(); let control = formGroup.get(element.formControlName); if (element.nestedControl) { control = control.get(element.nestedControl); } control.patchValue(''); expect(control.hasError('required')).toBeTruthy(); control.patchValue('Test'); expect(control.hasError('required')).toBeFalsy(); }); }); }); }); };
步骤2:调整主测试文件的调用方式
调用通用函数时,传递一个箭头函数() => component.formGroup,而不是直接传component.formGroup:
describe('Given a Physical Property Setup Component', () => { let component: PhysicalPropertySetupComponent; let fixture: ComponentFixture<PhysicalPropertySetupComponent>; let fields: Fields[] = [ new Fields('','field1','',''), new Fields('','field2','',''), new Fields('','field3','',''), new Fields('','field4','','') ]; beforeEach(() => { TestBed.configureTestingModule({ // ... 你的组件、依赖配置 }); fixture = TestBed.createComponent(PhysicalPropertySetupComponent); component = fixture.componentInstance; fixture.detectChanges(); // 关键:触发组件初始化,确保formGroup被创建 }); // 传递获取formGroup的函数,延迟到it执行时再取值 describe('Testing', componentTestFn(() => component.formGroup, fields)); });
补充说明
你提到在it中调用该函数能正常运行,正是因为it是测试的执行阶段,此时所有beforeEach钩子已经执行完毕,component和formGroup都已经被正确初始化。而describe是在测试套件加载时就执行的定义阶段,早于任何beforeEach和it,所以直接访问component会得到undefined。
内容的提问来源于stack exchange,提问作者Shreenil Patel
相关产品推荐
相关产品推荐

