简体   繁体   English

故障单元测试角度的反应形式字段

[英]trouble unit testing reactive form fields in angular

I'm learning Angular 2 and unit testing using @angular/cli 1.0.0-beta.30 and had a bit of success testing one aspect of a form field's validity, but not all.我正在使用 @angular/cli 1.0.0-beta.30 学习 Angular 2 和单元测试,并且在测试表单字段有效性的一个方面取得了一些成功,但不是全部。 I'm using an inline template in my component for the time being to remove a layer of complexity for now (a form template in a separate file introduces asynchronicity, correct?).我暂时在我的组件中使用内联模板来暂时消除一层复杂性(单独文件中的表单模板引入了异步性,对吗?)。

The ngOnInit() defines a name property that includes the validators for "required" and "minLength". ngOnInit()定义了一个name属性,其中包括“required”和“minLength”的验证器。 Currently an empty form field will correctly trigger the "required" validator but not the "minLength" validator.目前,一个空的表单字段将正确触发“required”验证器,但不会触发“minLength”验证器。 The name.errors array in the test does not contain any reference to required at all, name.errors['minLength'] returns undefined .测试中的name.errors数组根本不包含对 required 的任何引用, name.errors['minLength']返回undefined Does minLength need to be handled asynchronously? minLength 是否需要异步处理? I'm having trouble finding docs or examples that fit my problem.我无法找到适合我的问题的文档或示例。

// signup-form.component.ts
...
export class SignupFormComponent implements OnInit {

    user: FormGroup;

    constructor(private fb: FormBuilder) {
    }

    ngOnInit() {
        this.user = this.fb.group({
            name: ['', [Validators.required, Validators.minLength(2)]],
            account: this.fb.group({
                email: ['', Validators.required, Validators.pattern("[^ @]*@[^ @]*")],
                confirm: ['', Validators.required]
            })
        })
    }

    onSubmit({ value, valid }: { value: User, valid: boolean }) {
        console.log(value, valid);
    }

}

My test我的测试

// signup-form.component.spec.ts
import { SignupFormComponent } from './signup-form.component';

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

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [SignupFormComponent],
            imports: [
                ReactiveFormsModule,
                FormsModule
            ]
        })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(SignupFormComponent);
        component = fixture.componentInstance;
        component.ngOnInit();
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });

    it('form invalid when empty', () => {
        expect(component.user.valid).toBeFalsy();
    });

    it('name field validity', () => {
        let name = component.user.controls['name'];
        expect(name.valid).toBeFalsy();

        let errors = {};
        name.setValue("");
        errors = name.errors || {};
        expect(errors['required']).toBeTruthy(); // this works
        expect(errors['minLength']).toBeTruthy(); // this fails, "undefined"
    });

});

Answering your question回答你的问题

The name.errors['minLength'] returns undefined, Does minLength need to be handled asynchronously? name.errors['minLength']返回undefined,minLength是否需要异步处理?

You can just check the form for a specific error您可以只检查表单中的特定错误

expect(form.control.hasError('emailInvalid', ['email'])).toBe(true);

Below is a complete test下面是一个完整的测试

// signup-form.component.spec.ts
import { SignupFormComponent } from './signup-form.component';

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

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [SignupFormComponent],
            imports: [
                ReactiveFormsModule,
                FormsModule
            ]
        })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(SignupFormComponent);
        component = fixture.componentInstance;
        component.ngOnInit();
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });

    it('form invalid when empty', () => {
        expect(component.user.valid).toBeFalsy();
    });

    it('name field validity', () => {
        let name = component.user.controls['name'];
        expect(name.valid).toBeFalsy();

        name.setValue("");
        expect(name.hasError('required')).toBeTruthy();

        name.setValue("A");
        expect(name.hasError('minLength')).toBeTruthy();
    });

});
expect(name.hasError('minlength', ['minlength'])).toEqual(false);

Try this it worked for me试试这个对我有用

I believe it's because the validation key you're looking for is "minlength" non-camelCase, note the lower-case "l".我相信这是因为您正在寻找的验证密钥是“minlength”非驼峰式,请注意小写“l”。 I have personally run into this oddly named error property.我个人遇到过这个名字奇怪的错误属性。

'minLength' is handled in the same way as 'required' or any of the other Validators (eg maxLength, pattern). 'minLength'的处理方式与 'required' 或任何其他验证器(例如 maxLength、pattern)相同。

Unless your signup-form.component.ts code is truncated, I believe that you are missing a couple of things.除非您的 signup-form.component.ts 代码被截断,否则我相信您会遗漏一些东西。

Inside your FormBuilder, you need to subscribe to data changes.在您的 FormBuilder 中,您需要订阅数据更改。 this.user.valueChanges.subscribe(data => this.onValueChanged(data));

Then you need to declare the onValueChanged function.然后你需要声明 onValueChanged 函数。 Consult theAngular Form Validation cookbook for a generic onValueChanged function.查阅Angular Form Validation cookbook以获得通用的 onValueChanged 函数。

You'll also need to populate the formErrors object with the appropriate keys.您还需要使用适当的键填充 formErrors 对象。

formErrors = {
  'name': ''
 }

And supply validationMessages.并提供验证消息。

validationMessages = {
  'name': {
    'required': 'Name is required.',
    'minlength': 'Name must be at least 2 characters long.'
  }
 }
expect(errors['minlength']).toBeTruthy();

It is due to Validator.required priority, when such error exists - other validators are not even invoked and does not produce other errors.这是由于 Validator.required 优先级,当存在此类错误时 - 其他验证器甚至不会被调用并且不会产生其他错误。 You need to set some incorrect value for testing that specific part:)您需要设置一些不正确的值来测试该特定部分:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM