Weboldal keresés

Unit teszt Angular 4 direktíva @Input tulajdonsággal


Van egy AllowOnlyNumbers direktívám, amely a szövegdoboz típusú bemenetre van alkalmazva.

<input                         
                    [AllowOnlyNumbers]=true
                    [maxLength]= 'yearlyFieldMaxLength'
                    type="tel"
                    name="totalAnnualIncome"
                    formControlName="totalAnnualIncome"
                    [(ngModel)]="yearlyIncomeAmt"
                    (focus)="onFocusEnableToolTip('TotalAnnualIncome')" 
                    (focusout)="onFocusOutDisableToolTip('TotalAnnualIncome')" 
                     minlength="2"
                     autocomplete="off"/>

Egy nagyon egyszerű utasítás korlátozza a felhasználókat, hogy csak számokat írjanak a szövegdobozba.

import { Directive, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[AllowOnlyNumbers]'
})

/**
 * @method AllowOnlyNumbers
 * @desc This directive restricts the keyboard entry to numbers only.
 * Users can enter numbers and can use backspace, tab,enter, escape, end, home, left, right and del keys.
 * Usage: <input type = "text" [AllowOnlyNumbers] = true />
 */

export class AllowOnlyNumbers {

  constructor() { }

  @Input() AllowOnlyNumbers: boolean;
  /**
   * @methodspace AllowOnlyNumbers
   * @method onKeyDown
   * @desc It restricts the keyboard entry to numbers only.
   * @argument event
   * @returns returns only digit
   *
   */
  @HostListener('keydown', ['$event']) onKeyDown(event) {
    const e = event as KeyboardEvent;
    if (this.AllowOnlyNumbers) {
      // Allow: 8=Backspace, 9= Tab, 13=CR, 27=ESC, 35=END, 36=HOME, 37=Left, 39=Right, 46=DEL
      if ([8, 9, 13, 27, 35, 36, 37, 39, 46].indexOf(e.keyCode) !== -1) {
        return;
      }

      // Ensure that it is a number and stop the keypress
      if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
        e.preventDefault();
      }
    }
  }
}

Most, amikor az egységtesztet írom Jasmine használatával, nem tudom az @Input() AllowOnlyNumbers tulajdonságot true értékre állítani. Ez mindig undefined. Alább látható az UT fájlom. (Megjegyzés: a Keydown esemény létrejön)

import {ComponentFixture, TestBed} from '@angular/core/testing';
import { AllowOnlyNumbers } from './allow-only-numbers.directive';
import { Component, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';

@Component({
  template: `<input [AllowOnlyNumbers]= true type="text" name="totalAnnualIncome"  />`
})
// tslint:disable-next-line:no-unnecessary-class
class TestAllowOnlyNumbersComponent {
 //  allowNumbers = true;
}
fdescribe('Directive: AllowOnlyNumbers', () => {
  let component: TestAllowOnlyNumbersComponent;
  let fixture: ComponentFixture<TestAllowOnlyNumbersComponent>;
  let inputEl: DebugElement;
  let linkDes;
  let routerLinks;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [TestAllowOnlyNumbersComponent, AllowOnlyNumbers],
      schemas:      [ NO_ERRORS_SCHEMA ]
    });
    fixture = TestBed.createComponent(TestAllowOnlyNumbersComponent);
    component = fixture.componentInstance;
    inputEl = fixture.debugElement.query(By.css('input[name="totalAnnualIncome"]'));
  });

  it('keydown input', () => {
    inputEl.triggerEventHandler('keydown', {});
    fixture.detectChanges();
    expect(true).toBe(true);
  });

});

Ezt a linket használom referenciaként. Nem tudom a @Input() AllowOnlyNumbers tulajdonságot igazra állítani. Ez mindig undefined.

Válasz #1

Válasz a problémádra:

A TestAllowOnlyNumbersComponent-ben [AllowOnlyNumbers]="true"-nak kell lennie, nem [AllowOnlyNumbers]= true-nak.

Amit valójában csinálsz, az [AllowOnlyNumbers]=, ami nem rendel értéket az irányelv bemenetéhez.

A fixture.detectChanges()-t a triggerEventHandler előtt is érdemes meghívni, hogy elinduljon a kezdeti érték kötés, vagy még jobb, ha a beforeEach végén adod hozzá.

  beforeEach(() => {
    ...
    fixture.detectChanges();
  });

  it('keydown input', () => {
    inputEl.triggerEventHandler('keydown', {});
    expect(true).toBe(true);
  });

További megjegyzés az utasításodhoz:

Szerintem a direktívádban a keyCode-t cserélned kellene key-re, mivel úgy tűnik, hogy a keyCode elavult https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent. Szerintem a változtatás egyszerű kell legyen, a direktívádban csak beolvasod azt a key stringet és egy kódot a következő érték alapján: const code=e.key.charCodeAt()

Akkor létrehoznék a következő tesztet, hogy teszteljem az egyik billentyűt ebben az esetben az 'F' billentyűt:

  it('keydown input', () => {
    const event = new KeyboardEvent('keydown', { key: 'F' });
    inputEl.nativeElement.dispatchEvent(event);
    expect(event.defaultPrevented).toBe(true);
  });

Azt hiszem, ez működhet, amikor azt a változtatást elvégzik az irányelvben.

Kapcsolódó cikkek