Javascript 故障单元测试角度传感器中的反应型场

Javascript 故障单元测试角度传感器中的反应型场,javascript,forms,validation,unit-testing,angular,Javascript,Forms,Validation,Unit Testing,Angular,我正在学习Angular 2和使用@Angular/cli 1.0.0-beta.30进行单元测试,并在测试表单字段有效性的一个方面取得了一些成功,但不是全部。目前我在组件中使用内联模板来消除一层复杂性(单独文件中的表单模板引入异步性,对吗?) ngOnInit()定义了一个name属性,该属性包括“required”和“minLength”的验证器。当前,空表单字段将正确触发“必需”验证器,但不会触发“minLength”验证器。测试中的name.errors数组根本不包含对required的

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

ngOnInit()
定义了一个
name
属性,该属性包括“required”和“minLength”的验证器。当前,空表单字段将正确触发“必需”验证器,但不会触发“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"
    });

});
//signup-form.component.spec.ts
从“./signup form.component”导入{SignupFormComponent};
描述('SignupFormComponent',()=>{
let组件:SignupFormComponent;
let夹具:组件夹具;
beforeach(异步(()=>{
TestBed.configureTestingModule({
声明:[SignupFormComponent],
进口:[
反应形式模块,
FormsModule
]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(SignupFormComponent);
组件=fixture.componentInstance;
组件。ngOnInit();
fixture.detectChanges();
});
它('应该创建',()=>{
expect(component.toBeTruthy();
});
它('空时表单无效',()=>{
expect(component.user.valid).toBeFalsy();
});
它('名称字段有效性',()=>{
让name=component.user.controls['name'];
expect(name.valid).toBeFalsy();
让错误={};
name.setValue(“”);
errors=name.errors |{};
expect(errors['required'])。toBeTruthy();//这很有效
预期(错误['minLength'])。toBeTruthy();//此操作失败,“未定义”
});
});

以与“必需”或任何其他验证器(例如maxLength、pattern)相同的方式处理“minLength”

除非您的signup-form.component.ts代码被截断,否则我认为您缺少一些东西

在FormBuilder中,您需要订阅数据更改。
this.user.valueChanges.subscribe(数据=>this.onValueChanged(数据))

然后需要声明onValueChanged函数。有关通用的onValueChanged函数,请参阅

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

formErrors = {
  'name': ''
 }
并提供验证消息

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

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

回答你的问题

name.errors['minLength']返回未定义,是否需要指定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();
    });

});
//signup-form.component.spec.ts
从“./signup form.component”导入{SignupFormComponent};
描述('SignupFormComponent',()=>{
let组件:SignupFormComponent;
let夹具:组件夹具;
beforeach(异步(()=>{
TestBed.configureTestingModule({
声明:[SignupFormComponent],
进口:[
反应形式模块,
FormsModule
]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(SignupFormComponent);
组件=fixture.componentInstance;
组件。ngOnInit();
fixture.detectChanges();
});
它('应该创建',()=>{
expect(component.toBeTruthy();
});
它('空时表单无效',()=>{
expect(component.user.valid).toBeFalsy();
});
它('名称字段有效性',()=>{
让name=component.user.controls['name'];
expect(name.valid).toBeFalsy();
name.setValue(“”);
expect(name.hasError('required')).toBeTruthy();
名称。设定值(“A”);
expect(name.hasError('minLength')).toBeTruthy();
});
});

试试这个,它对我有效

这是由于Validator.required priority,当存在这样的错误时-甚至不会调用其他验证器,也不会产生其他错误。您需要设置一些不正确的值来测试该特定部件:)

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