6

このガイドhttps://angular.io/docs/ts/latest/cookbook/form-validation.html#!#custom-validationに従って、カスタム角度(Angular 2.0.0)検証を書いています。

@Directive({
  selector: '[ngModel][emailValidator]',
  providers: [{provide: NG_VALIDATORS, useExisting: EmailValidatorDirective, multi: true}]
})
export class EmailValidatorDirective implements Validator 

今、カスタム検証ディレクティブに単体テストを追加しようとしています。

beforeEach(() => {
      fixture = TestBed.createComponent(EmailComponent);
      component = fixture.componentInstance;
      de = fixture.debugElement;
      el = de.nativeElement;
      component = de.componentInstance;
      emailField = de.query(By.css('input')).nativeElement;
    });

私はこれらすべてのオブジェクトにアクセスしていますが、私の入力の有効性に関する情報は誰も持っていません。単体テスト内で私の入力の NgControl にアクセスする方法、または有効/無効(カスタム検証)入力フィールドを確認する方法を知っている人はいますか?

4

3 に答える 3

13

あなたがする必要があるのは、NgForm. それを理解するのにしばらく時間がかかりました。から取得できると思っていましたが、子1debugElementから取得する必要があるようです。

let form: NgForm = fixture.debugElement.children[0].injector.get(NgForm);

フォームグループから個々のコントロールを取得できます

let emailControl = form.control.get('email');
expect(emailControl.valid).toBe(true);

または、特定のエラーについてフォームを確認することもできます

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

以下は完全なテストです

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 !== 'peeskillet@stackoverflow.com') {
      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 = 'bad@email.com';
      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 = 'peeskillet@stackoverflow.com';
      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);
    });
  }));
});

1 -ソース コード テストで見つかった

于 2016-10-07T13:44:18.710 に答える