我通过检查按下了哪个按钮,编写了一个防止Keyboarddefaults的指令。我正在尝试对指令进行单元测试。我可以看到该指令在应用程序中运行,或者在我将console.log()放入指令中时看到。不起作用的是键入的字母不会设置到组件ngModelField中。
我已经尝试了很多东西,包括夹具.detectChanges(),夹具.whenStable()等。
我的指令:
private allowed = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',]
@HostListener('keydown', ['$event'])
onKeyDown(e: KeyboardEvent) {
if (this.allowed.indexOf(e.key) > -1) {
console.log('allowed');
return;
}
console.log('preventdefault');
e.preventDefault();
}
我的单元测试:
describe('OnlyDecimalDirective', () => {
let fixture: ComponentFixture<MockOnlyDecimalComponent>;
let component: MockOnlyDecimalComponent;
let input: HTMLInputElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [OnlyDecimalDirective, MockOnlyDecimalComponent],
imports: [FormsModule],
});
fixture = TestBed.createComponent(MockOnlyDecimalComponent);
component = fixture.componentInstance;
input = fixture.debugElement.query(By.css('input')).nativeElement;
}));
it('sollte Ziffern akzeptieren', () => {
fixture.detectChanges();
let keyDown = new KeyboardEvent('keydown', { key: '5' });
input.dispatchEvent(keyDown);
console.log(component.text)
});
});
我的单元测试的MockComponent
@Component({ template: '<input onlyDecimal [(ngModel)]="text" type="string">' })
export class MockOnlyDecimalComponent {
public text = '';
}
我需要测试结果。因此,我希望如果触发Keydown事件,则component.text字段将获取我在新KeyBoardEvent中发布的键的值:
let keyDown = new KeyboardEvent('keydown', { key: '5' }); // key: 's' should prevent default
我可以看到console.log()出现了,但是我无法测试最终结果,因为我不会在component.text中显示
有人要求我进行Stackblitz: https://stackblitz.com/edit/angular-testing-callback-cuqg9m
答案 0 :(得分:1)
input.dispatchEvent(keyDown);
console.log(component.text);
在DOM元素上调用dispatchEvent()
不会更新输入文本。使用手动DOM事件,您不能非常轻松地模拟用户交互。模拟键盘输入所涉及的DOM事件比keydown
事件要多得多。当用户在键盘上键入内容时,将发生诸如更改事件,焦点事件和多个键盘事件之类的事情。
例如,如果用户从剪贴板粘贴文本或使用浏览器的自动完成功能,则您的指令不起作用。
如果您想限制表单的值,则需要构建一个自定义模板驱动器验证器来更改输入值。