typescript Angular 2 自定义验证单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39910017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular 2 Custom validation unit testing
提问by Krasimir Kirilov
i'm writing custom angular(Angular 2.0.0) validation, following this guide https://angular.io/docs/ts/latest/cookbook/form-validation.html#!#custom-validation.
我正在编写自定义角度(Angular 2.0.0)验证,遵循本指南https://angular.io/docs/ts/latest/cookbook/form-validation.html#!#custom-validation。
@Directive({
selector: '[ngModel][emailValidator]',
providers: [{provide: NG_VALIDATORS, useExisting: EmailValidatorDirective, multi: true}]
})
export class EmailValidatorDirective implements Validator
Now i'm trying to add unit test to my custom validation directive.
现在我正在尝试将单元测试添加到我的自定义验证指令中。
beforeEach(() => {
fixture = TestBed.createComponent(EmailComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
el = de.nativeElement;
component = de.componentInstance;
emailField = de.query(By.css('input')).nativeElement;
});
I'm accessing all these object, but no one has any information about the validity of my input. Does anyone has any idea how to access the NgControl of my input inside the Unit Tests, or how can i check for valid/invalid(custom validation) input field.
我正在访问所有这些对象,但没有人知道我输入的有效性的任何信息。有没有人知道如何在单元测试中访问我输入的 NgControl,或者我如何检查有效/无效(自定义验证)输入字段。
回答by Paul Samsotha
What you need to do is get the injector that has the NgForm
. It took me a while to figure it out. I thought you could just get it from the debugElement
, but it looks like you need to get it from it's child1.
您需要做的是获取带有NgForm
. 我花了一段时间才弄明白。我以为你可以从 1 那里得到它debugElement
,但看起来你需要从它的孩子1那里得到它。
let form: NgForm = fixture.debugElement.children[0].injector.get(NgForm);
The you can just get individual controls from the form group with
您可以从表单组中获取单个控件
let emailControl = form.control.get('email');
expect(emailControl.valid).toBe(true);
Or you can just check the form for a specific error
或者您可以只检查表单是否存在特定错误
expect(form.control.hasError('emailInvalid', ['email'])).toBe(true);
Below is a complete test
下面是一个完整的测试
import { Component, forwardRef, Directive } from '@angular/core';
import { TestBed, getTestBed, async } from '@angular/core/testing';
import { FormsModule, NG_VALIDATORS, Validator, AbstractControl, NgForm } from '@angular/forms';
import { dispatchEvent } from '@angular/platform-browser/testing/browser_util';
import { By } from '@angular/platform-browser';
@Directive({
selector: '[ngModel][validEmail]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => EmailValidatorDirective),
multi: true
}
]
})
class EmailValidatorDirective implements Validator {
validate(c: AbstractControl): { [key: string]: any } {
if (c.value !== '[email protected]') {
return { notPeeskillet: true };
}
return null;
}
}
@Component({
template: `
<form>
<input name="email" [ngModel]="email" validEmail />
</form>
`
})
class TestComponent {
email;
}
describe('component: TestComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FormsModule],
declarations: [TestComponent, EmailValidatorDirective]
});
});
it('should validate', async(() => {
let fixture = TestBed.createComponent(TestComponent);
let comp = fixture.componentInstance;
let debug = fixture.debugElement;
let input = debug.query(By.css('[name=email]'));
fixture.detectChanges();
fixture.whenStable().then(() => {
input.nativeElement.value = '[email protected]';
dispatchEvent(input.nativeElement, 'input');
fixture.detectChanges();
let form: NgForm = debug.children[0].injector.get(NgForm);
let control = form.control.get('email');
expect(control.hasError('notPeeskillet')).toBe(true);
expect(form.control.valid).toEqual(false);
expect(form.control.hasError('notPeeskillet', ['email'])).toEqual(true);
input.nativeElement.value = '[email protected]';
dispatchEvent(input.nativeElement, 'input');
fixture.detectChanges();
expect(control.hasError('notPeeskillet')).toBe(false);
expect(form.control.valid).toEqual(true);
expect(form.control.hasError('notPeeskillet', ['email'])).toEqual(false);
});
}));
});
回答by Cameron Vogler
The above best answer didn't work for me but I was able to test my custom validator in the following way:
上面的最佳答案对我不起作用,但我能够通过以下方式测试我的自定义验证器:
const associateRateControl = component.distributionSettingsForm.controls['associateRate'];
associateRateControl.setValue('plus ultra');
fixture.detectChanges();
expect(component.distributionSettingsForm.hasError('noCatalog')).toEqual(true);