以角形式添加验证器

时间:2018-05-30 11:51:24

标签: javascript html angular

我正在测试这个html表单:

 <input #nhcInput type="text" class="form-control" name="nhc" id="field_nhc"
	                [(ngModel)]="paciente.nhc" maxlength="38" pattern="[0-9]+"/>
	            <div [hidden]="!(editForm.controls.nhc?.dirty && editForm.controls.nhc?.invalid)">
	                <small class="form-text text-danger"
	                   [hidden]="!editForm.controls.nhc?.errors?.maxlength" jhiTranslate="entity.validation.maxlength" translateValues="{ max: 38 }">
	                   This field cannot be longer than 38 characters.
	                </small>
	               

TEH RESULT {{nhcInput.className}} //This line prints ng-valid/ dirty, touched correctly

我的组件中有这个:

    paciente: Paciente = {nhc: '23423' } as Paciente;

  it ('NHC cannot have more than 38 characters', async(() => {
               
                      comp.paciente.nhc = 'rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr' ;             
                      console.log(fixture.nativeElement.querySelector('input[name="nhc"]').className);
                      fixture.detectChanges();              
                     expect(fixture.nativeElement.querySelector('input[name="nhc"]').className.includes('ng-invalid')).toEqual(true);
                      })); 

现在我想通过检查vaidator来测试有效性。 console.log只打印出没有验证器类型的表单控件,因为它没有找到它。

我在我的组件中为这个fild设置了一个验证器:

@ViewChild('editForm') editForm: any;
 editform.controls["nhc"].setValidators([ Validators.maxLength(38)]);

但这不起作用。我在这做错了吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

您的问题来自于您不按顺序执行操作而不依赖框架进行测试。

I made a sandbox进行工作测试,随时查看。现在解释一下:

让我们从组件开始:

@Component({
  selector: 'hello',
  template: `
  <form #myForm="ngForm">
    <input type="text" maxlength="20" name="patient" id="patient" [(ngModel)]="patient">
  </form>
  `,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
  @ViewChild('myForm') myForm: NgForm;
  patient: string;
}

一个非常简单的组件,具有模板驱动的表单和基本的验证和绑定。

如果你这样做

ngOnInit() {
  console.log(this.myForm.controls);
  setTimeout(() => console.log(this.myForm.controls));
}

您会看到undefined{ patient: FormControl }。发生这种情况是因为您在进行测试之前不等待视图初始化。这意味着测试无法找到表单控件,因此无法通过。

现在进行测试:

import { Component } from '@angular/core';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { HelloComponent } from './hello.component';

import { FormsModule } from '@angular/forms';

describe('HelloComponent', () => {
  let fixture: ComponentFixture<HelloComponent>;
  let component: HelloComponent;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [FormsModule],
      declarations: [HelloComponent]
    });

    fixture = TestBed.createComponent(HelloComponent);
    component = fixture.debugElement.children[0].componentInstance;

    fixture.detectChanges();
  });

  it('should be invalid with more than 20 chars', async(() => {
    setTimeout(() => {
      component.myForm.controls['patient'].setValue('ddddddddddddddddddddd'); // 21
      fixture.detectChanges();
      expect(component.myForm.control.invalid).toEqual(true);
    });
  }));
});

启动非常基本,配置了测试台并检测到更改。

现在是您测试的部分:首先必须等待组件加载超时,然后,您需要使用框架在表单上设置值:

component.myForm.controls['patient'].setValue('ddddddddddddddddddddd'); // 21

这会将21 d输入到输入中,这使其无效。之后,您需要触发更改检测,现在您可以使用

进行预期
expect(component.myForm.control.invalid).toEqual(true);

这将采用窗体作为控件,这意味着它具有FormControl具有的所有属性和功能。其中,您可以找到invalid属性,该属性指出您的控件是否处于无效状态。

同样,我必须声明这种测试没用,因为你基本上试图看看框架是否正常工作。那不是你的工作,那是Angular团队的工作。如果你想测试一些东西,你应该测试表单无效状态时无法提交,这是一个业务规则(我猜)并防止副作用(不像这个测试)。

相关问题