【问题标题】:trouble unit testing reactive form fields in angular麻烦单元测试角度的反应性表单字段
【发布时间】:2017-06-27 21:11:04
【问题描述】:

我正在学习 Angular 2 和使用 @angular/cli 1.0.0-beta.30 进行单元测试,并在测试表单字段有效性的一个方面取得了一些成功,但不是全部。我暂时在我的组件中使用内联模板来消除一层复杂性(单独文件中的表单模板引入了异步性,对吗?)。

ngOnInit() 定义了一个 name 属性,其中包括“required”和“minLength”的验证器。目前,一个空的表单域将正确触发“required”验证器,但不会触发“minLength”验证器。测试中的name.errors数组根本不包含任何对required的引用,name.errors['minLength']返回undefined。 minLength 是否需要异步处理?我无法找到适合我的问题的文档或示例。

// 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);
    }

}

我的测试

// 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"
    });

});

【问题讨论】:

    标签: javascript forms validation unit-testing angular


    【解决方案1】:

    回答你的问题

    name.errors['minLength'] 返回 undefined,minLength 是否需要 异步处理?

    您可以只检查表单中的特定错误

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

    下面是完整的测试

    // 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();
        });
    
    });
    

    【讨论】:

      【解决方案2】:
      expect(name.hasError('minlength', ['minlength'])).toEqual(false);
      

      试试这个对我有用

      【讨论】:

        【解决方案3】:

        我相信这是因为您要查找的验证密钥是“minlength”非驼峰式,请注意小写“l”。我个人遇到过这个名字奇怪的错误属性。

        【讨论】:

          【解决方案4】:

          'minLength' 的处理方式与“required”或任何其他验证器(例如 maxLength、模式)相同。

          除非您的 signup-form.component.ts 代码被截断,否则我相信您遗漏了一些东西。

          在您的 FormBuilder 中,您需要订阅数据更改。 this.user.valueChanges.subscribe(data =&gt; this.onValueChanged(data));

          然后你需要声明 onValueChanged 函数。请参阅 Angular Form Validation cookbook 了解通用 onValueChanged 函数。

          您还需要使用适当的键填充 formErrors 对象。

          formErrors = {
            'name': ''
           }
          

          并提供验证消息。

          validationMessages = {
            'name': {
              'required': 'Name is required.',
              'minlength': 'Name must be at least 2 characters long.'
            }
           }
          

          【讨论】:

            【解决方案5】:

            这是由于 Validator.required 优先级,当此类错误存在时 - 甚至没有调用其他验证器并且不会产生其他错误。您需要设置一些不正确的值来测试该特定部分:)

            【讨论】:

              【解决方案6】:
              expect(errors['minlength']).toBeTruthy();
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-11-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多