单元测试 angular 4 指令具有 @input 属性
Unit test angular 4 directive having @input property
我有一个应用于输入类型文本框的指令 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 编写单元测试用例时,我无法将 @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);
});
});
我正在使用 this link 作为参考。我无法将 @Input() AllowOnlyNumbers
属性 设置为 true。这始终是未定义的。
您问题的回答:
在TestAllowOnlyNumbersComponent
中应该是[AllowOnlyNumbers]="true"
而不是[AllowOnlyNumbers]= true
。
你实际上在做的是[AllowOnlyNumbers]=
,它没有为指令的输入分配任何值。
此外,您应该将 fixture.detectChanges()
移动到 triggerEventHandler
之前以触发初始值绑定,或者更好的做法是将其添加到 beforeEach
的末尾
beforeEach(() => {
...
fixture.detectChanges();
});
it('keydown input', () => {
inputEl.triggerEventHandler('keydown', {});
expect(true).toBe(true);
});
还有关于您的指令的附加评论:
我认为您应该在指令中将 keyCode
替换为 key
,因为看起来 keyCode
已被弃用 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent。
我认为更改应该很容易,在您的指令中,您只需读取该键字符串和基于该值的代码 const code = e.key.charCodeAt()
然后我会创建以下测试,在这种情况下测试其中一个键 'F' key:
it('keydown input', () => {
const event = new KeyboardEvent('keydown', { key: 'F' });
inputEl.nativeElement.dispatchEvent(event);
expect(event.defaultPrevented).toBe(true);
});
我想这在指令中进行更改时可能会起作用。
我有一个应用于输入类型文本框的指令 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 编写单元测试用例时,我无法将 @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);
});
});
我正在使用 this link 作为参考。我无法将 @Input() AllowOnlyNumbers
属性 设置为 true。这始终是未定义的。
您问题的回答:
在TestAllowOnlyNumbersComponent
中应该是[AllowOnlyNumbers]="true"
而不是[AllowOnlyNumbers]= true
。
你实际上在做的是[AllowOnlyNumbers]=
,它没有为指令的输入分配任何值。
此外,您应该将 fixture.detectChanges()
移动到 triggerEventHandler
之前以触发初始值绑定,或者更好的做法是将其添加到 beforeEach
beforeEach(() => {
...
fixture.detectChanges();
});
it('keydown input', () => {
inputEl.triggerEventHandler('keydown', {});
expect(true).toBe(true);
});
还有关于您的指令的附加评论:
我认为您应该在指令中将 keyCode
替换为 key
,因为看起来 keyCode
已被弃用 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent。
我认为更改应该很容易,在您的指令中,您只需读取该键字符串和基于该值的代码 const code = e.key.charCodeAt()
然后我会创建以下测试,在这种情况下测试其中一个键 'F' key:
it('keydown input', () => {
const event = new KeyboardEvent('keydown', { key: 'F' });
inputEl.nativeElement.dispatchEvent(event);
expect(event.defaultPrevented).toBe(true);
});
我想这在指令中进行更改时可能会起作用。