比方咱们以后创立了一个如下的异步验证器,咱们想要写一个单元测试来保障其准确性。
vehicleBrandNameNotExist(): AsyncValidatorFn {return (control: AbstractControl): Observable<ValidationErrors | null> => {if (control.value === '') {return of(null);
}
return this.vehicleBrandService.existByName(control.value).pipe(map(exists => exists ? {vehicleBrandNameExist: true} : null));
};
}
咱们再 mockApi 中设置了如果 name 为‘车辆品牌’则返回 true, 若为‘车辆’则返回 false, 其余状况随即返回。
if(name === '车辆品牌') {console.log('return true');
return true;
}
if(name === '车辆')
return false;
return randomNumber(5) < 2;
起初想的是只有像这样在单元测试中创立一个 formControl 而后再设置它的值为 ’ 车辆品牌 ’ 而后再判定 formControl.errors.vehicleBrandNameExist
为 true 即可,然而零碎会产生报错提醒 formControl.errors.vehicleBrandNameExist
为 undefined;
之后又退出了 setTimeout 进行延时解决
beforeEach(() => {asyncValidate = TestBed.inject(VehicleBrandAsyncValidator);
service = TestBed.inject(VehicleBrandService);
});
fit('should create an instance', async () => {expect(asyncValidate).toBeTruthy();
let formControl = new FormControl('', asyncValidate.vehicleBrandNameNotExist());
formControl.setValue('车辆品牌');
setTimeout(() => console.log(formControl.errors.vehicleBrandNameExist), 500);
});
通过输入发现还是为 undefined. 之后我有别离在验证器 C 层,M 层,和 mockApi 中进行输入相应的断点,发现基本没有执行到 mockApi 中,只执行到了 M 层。
之后我又尝试在相应的模块的单元测试中进行如下测试,发现能够实现咱们想要的成果。
beforeEach(() => {fixture = TestBed.createComponent(AddComponent);
asyncValidate = TestBed.inject(VehicleBrandAsyncValidator);
component = fixture.componentInstance;
fixture.detectChanges();});
fit('should create', () => {component.formGroup.get(component.formKeys.name).setValue('车辆品牌');
setTimeout(() => console.log(component.formGroup.get(component.formKeys.name).errors.vehicleBrandNameExist), 100);
});
这时问题就呈现了,咱们只是把 formControl 申明在了 component 中就能够实现咱们想要的成果,formControl 只是扭转了获取形式——从间接创立获取变成了在 component 中创立,再通过 component 获取。为什么就会呈现这样的后果呢。
在此期间还可能遇到以下问题:
let asyncValidator: VehicleBrandAsyncValidator;
let formControl = new FormControl('', asyncValidator.vehicleBrandNameNotExist() );
formControl.setValue('车辆品牌');
如果咱们这样应用 VehicleBrandAsyncValidator
的话会产生报错,咱们会发现 asyncValidator
为空,咱们须要手动通过一下代码将 VehicleBrandAsyncValidator 注入进来。
asyncValidate = TestBed.inject(VehicleBrandAsyncValidator);
我很还有可能在执行上述代码时可能什么都不会执行即不会触发验证器,那么很有可能是因为在
let formControl = new FormControl('', asyncValidator.vehicleBrandNameNotExist() );
中咱们将其写为了
let formControl = new FormControl('', asyncValidator.vehicleBrandNameNotExist);
这种状况在 C 层编辑器会通知咱们类型不匹配,然而在单元测试中不会。