比方咱们以后创立了一个如下的异步验证器,咱们想要写一个单元测试来保障其准确性。
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层编辑器会通知咱们类型不匹配,然而在单元测试中不会。