首页 > 解决方案 > Angular 中的单元测试无法读取 null 的“setValidators”

问题描述

实际上,我正在规范文件中为我们解决方案中的一个组件编写测试用例。我们正在使用 FormGroup 并像这样在其中使用一些验证-

我的组件包含-

export class FormFieldInputV2Component implements OnInit, AfterViewInit {

  @Input() configData: any;
  @Input() frmGroup: FormGroup;
  @Input() frmBuilder:FormBuilder;

  constructor() {}
  
  placeHolder = "";
  validationType: string = "";

  @ViewChild('formFieldWrapper', null) formFieldWrapper;
  
  

    ngOnInit() {
    
        this.configData.validation.forEach((element) => {
          if (element === "Numeric") {
            this.validationType = element;
            this.frmGroup.get(this.configData.name).setValidators(Validators.min(1));
            this.frmGroup
              .get(this.configData.name)
              .setValidators(Validators.pattern(new RegExp("^0*[1-9]\\d*$")));
          } else if (element === "Decimal") {
            this.validationType = element;
            this.frmGroup.get(this.configData.name).setValidators(Validators.min(1));
            this.frmGroup
              .get(this.configData.name)
              .setValidators(
                Validators.pattern(
                  new RegExp("^\\s*(?=.*[1-9])\\d*(?:\\.\\d{1,99})?\\s*$")
                )
              );
          } else if (element === "DecimalWithMaxlength") {
            this.validationType = element;
            this.frmGroup
              .get(this.configData.name)
              .setValidators(
                Validators.pattern(
                  new RegExp(/^\s*(?=.*[1-9])\d{1,3}(?:\.\d{1,2})?\s*$/)
                )
              );
          }
          if (element === "NoSpecialCharacter") {
            this.validationType = element;
            this.frmGroup
              .get(this.configData.name)
              .setValidators(
                Validators.pattern(new RegExp("^((?![$<>?%&*#!~` +]).).*\\S*$"))
              );
          }
          if (element === "Email") {
            let newexp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
            this.validationType = element;
            this.frmGroup
              .get(this.configData.name)
              .setValidators(Validators.pattern(newexp));
          }
          if (element === "hidden") {
            if (!(this.frmGroup.get(this.configData.name)["hidden"] === false)) {
              this.frmGroup.get(this.configData.name)["hidden"] = true;
            }
          }
        }, this);
      }
    
        ngAfterViewInit() {
          this.frmGroup.get(this.configData.name).statusChanges.subscribe(x => {
              if(this.frmGroup.get(this.configData.name).value == undefined || this.frmGroup.get(this.configData.name).value == null){
                this.formFieldWrapper.nativeElement.classList.remove("dhl-form-field--is-active",
                  "dhl-form-field--set-borderRed", "dhl-form-field--set-border-success", "dhl-form-field--is-filled");
              }
          });
        }

我的规格包含-

fdescribe('FormFieldInputV2Component', () => {

  let component: FormFieldInputV2Component;

  let fixture: ComponentFixture<FormFieldInputV2Component>;

  beforeEach(() => {

    fixture = TestBed.createComponent(FormFieldInputV2Component);

    component = fixture.componentInstance;
    
    component.frmGroup = formBuilder.group({
      firstName: null,
      lastName: null
    });

    fixture.detectChanges();
    component.ngOnInit();
    fixture.detectChanges();
  });

  it('should create', () => {

    expect(component).toBeTruthy();
  });

  it('should run #ngAfterViewInit()', async () => {

  it('form should be invalid', async(() => {

      fixture.detectChanges();

      component.frmGroup.get(component.configData.name).setValidators(Validators.min(5));

      expect(component.frmGroup.valid).toBeFalsy();
    }));
  
    it('form should be valid', async(() => {
      component.frmGroup.get(component.configData.name).setValidators(Validators.min(1));
      expect(component.frmGroup.valid).toBeTruthy();
    }));

    component.configData.name = 'name';
    component.configData.validation=["NoSpecialCharacter"];
    component.formFieldWrapper = component.formFieldWrapper || {};
    component.formFieldWrapper.nativeElement = {
      classList: {
        remove: function() {}
      }
    };
    component.ngAfterViewInit();
  });

  // new test by ngentest

  it('should run #onBlurSetActive()', async () => {

    component.configData = component.configData || {};

    component.configData.placeHolder = 'placeHolder';

    component.configData.validation=["NoSpecialCharacter"];

    component.onBlurSetActive({}, {});

  });

运行 ng test 后,它给了我错误“FormFieldInputV2Component 应该运行 #ngAfterViewInit() FAILED TypeError: Cannot read property 'setValidators' of null”

标签: angular

解决方案


我不确定,但我认为在 beforeEach 块中而不是将 formgroup 属性设置为 null 您需要为它们分配 formControls

component.frmGroup = formBuilder.group({
      firstName: new FormControl(),
      lastName: new FormControl()
    });

您正在尝试在 ngOnInit 中调用 setValidator on null


推荐阅读