Angular中FormGroup的valueChanges内部代码单元测试咨询
测试FormGroup valueChanges 实现全代码覆盖率
先搭好测试基础:初始化组件、表单实例,把要验证的updateDateField方法用spy监听,方便后续断言调用情况:
let component: YourComponent; let fixture: ComponentFixture<YourComponent>; beforeEach(() => { TestBed.configureTestingModule({ declarations: [YourComponent], providers: [/* 填你组件需要的服务依赖 */] }); fixture = TestBed.createComponent(YourComponent); component = fixture.componentInstance; // 初始化测试用的表单 component.partyForm = new FormGroup({ // 按你实际表单结构定义控件,比如name: new FormControl('') }); // 初始化销毁订阅的Subject component.ngUnsubscribe = new Subject<void>(); // 监听updateDateField方法,不执行实际逻辑 spyOn(component, 'updateDateField'); fixture.detectChanges(); });
场景1:表单启用时,值变化触发updateDateField
因为代码里用了debounceTime(100),所以用fakeAsync和tick模拟时间流逝:
it('调用updateDateField当表单启用且值变化时', fakeAsync(() => { // 确保表单处于启用状态 component.partyForm.enable(); // 修改表单值 component.partyForm.patchValue({ name: '测试值' }); // 触发组件变更检测 fixture.detectChanges(); // 等待防抖时间结束 tick(100); // 验证方法被正确调用,参数是表单最新值 expect(component.updateDateField).toHaveBeenCalledWith({ name: '测试值' }); }));
场景2:表单禁用时,值变化不触发updateDateField
覆盖代码里的if (this.partyForm.enabled)分支:
it('表单禁用时,值变化不调用updateDateField', fakeAsync(() => { // 禁用表单 component.partyForm.disable(); // 修改表单值 component.partyForm.patchValue({ name: '测试值' }); fixture.detectChanges(); tick(100); // 验证方法完全没被调用 expect(component.updateDateField).not.toHaveBeenCalled(); }));
场景3:验证distinctUntilChanged生效(补全分支覆盖)
确保相同值重复设置时,不会重复触发方法:
it('值未变化时,不重复调用updateDateField', fakeAsync(() => { component.partyForm.enable(); const testValue = { name: '初始值' }; component.partyForm.setValue(testValue); fixture.detectChanges(); tick(100); // 第一次设置值会触发一次 expect(component.updateDateField).toHaveBeenCalledTimes(1); // 再次设置完全相同的值 component.partyForm.setValue(testValue); fixture.detectChanges(); tick(100); // 方法只被调用一次,因为distinctUntilChanged过滤了重复值 expect(component.updateDateField).toHaveBeenCalledTimes(1); }));
场景4:验证takeUntil终止订阅(覆盖订阅销毁逻辑)
确保ngUnsubscribe发出信号后,后续值变化不再触发方法:
it('ngUnsubscribe发出信号后,停止监听值变化', fakeAsync(() => { component.partyForm.enable(); // 发出销毁订阅的信号 component.ngUnsubscribe.next(); component.ngUnsubscribe.complete(); // 修改表单值 component.partyForm.patchValue({ name: '测试值' }); fixture.detectChanges(); tick(100); // 验证方法没被调用 expect(component.updateDateField).not.toHaveBeenCalled(); }));
内容的提问来源于stack exchange,提问作者dvln
相关产品推荐
相关产品推荐

