具有@input属性的单元测试角度4指令

时间:2018-03-26 12:58:46

标签: angular unit-testing typescript karma-jasmine angular2-directives

我有一个指令AllowOnlyNumbers,它适用于输入类型文本框。

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

一个非常简单的指令限制用户只在文本框中放入数字。

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

现在,在使用jasmine编写Unit测试用例时,我无法将@Input() AllowOnlyNumbers属性设置为true。这总是未定义的。 下面是我的UT文件。 (注意:Keydown事件被解雇)

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

});

我使用issue作为参考。我无法将@Input() AllowOnlyNumbers属性设置为true。这总是未定义的。

1 个答案:

答案 0 :(得分:4)

回答您的问题:

[AllowOnlyNumbers]="true"中的[AllowOnlyNumbers]= true不是TestAllowOnlyNumbersComponent

你实际做的是[AllowOnlyNumbers]=,它没有为指令的输入分配任何值。

此外,您应该在fixture.detectChanges()之前移动triggerEventHandler以触发初始值绑定,或者更好的是在beforeEach

的末尾添加 beforeEach(() => { ... fixture.detectChanges(); }); it('keydown input', () => { inputEl.triggerEventHandler('keydown', {}); expect(true).toBe(true); });
keyCode

还有关于您的指令的其他评论:

我认为您应该在指令中将key替换为keyCode,因为看起来const code = e.key.charCodeAt()已被弃用https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent。 我认为改变应该很容易,在你的指令中,你只需读取该关键字符串和基于该值的代码 it('keydown input', () => { const event = new KeyboardEvent('keydown', { key: 'F' }); inputEl.nativeElement.dispatchEvent(event); expect(event.defaultPrevented).toBe(true); });

然后我会创建以下测试,以测试这种情况下'F'键中的一个键:

subscribeOn

我想在指令中进行更改时可能会有效。