如何解决Angular和Jasmine:使用模拟按键触发ngModelChange吗?
我正在尝试编写一个单元测试,以证明用户的每次按键操作都会触发一个(ngModelChange)
事件,我将其设置为调用名为onValueChange()
的函数。此函数更新组件的内部值
我可以证明,在测试环境中,在实际键盘上的实际按键上,此事件在每个按键上触发,并更新了组件的formGroup值,这是预期的结果,但是我想为我的单元测试自动化此按键。我也不能使用jQuery。
我尝试过手动设置nativeElement.value
,并且尝试了多种模拟按键的方法,但是没有一种方法可以像物理按键一样触发ngModelChange
事件按。
这是我的规格初稿,它不会触发ngModelChange
,但是输入文本框中的任何物理按键都可以:
fit('should call onValueChange after new input is entered',fakeAsync(() => {
let textInputEl: DebugElement = fixture.debugElement.query(
By.css('input.form-control')
);
let HTMLInput = textInputEl.nativeElement;
HTMLInput.value = 'world';
tick();
fixture.detectChanges();
expect(component.formGroup.value.textInputState).toEqual('world');
}));
这是我的另一本规范草案,试图模拟物理按键(因此ngModelChange
)无效:
fit('should call onValueChange after new input is entered',fakeAsync(() => {
let textInputEl: DebugElement = fixture.debugElement.query(
By.css('input.form-control')
);
let HTMLInput = textInputEl.nativeElement;
HTMLInput.value = 'world';
HTMLInput.select();
document.addEventListener('keydown',function(e){
console.log('keydown detected');
})
const event = new KeyboardEvent("keypress",{
"key": "Enter"
});
HTMLInput.dispatchEvent(event);
HTMLInput.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
HTMLInput.dispatchEvent(new KeyboardEvent('keydown',{'key':'b'}));
tick();
fixture.detectChanges();
HTMLInput.dispatchEvent(new KeyboardEvent('keyup',{'key':'b'}));
tick();
fixture.detectChanges();
expect(component.formGroup.value.textInputState).toEqual('world');
}));
组件内部的两个相关功能:
onValueChange(newValue: T) {
console.log('onValueChange() just called!');
this.value = newValue;
this.valueChange.emit(this.value);
this.emitSerializableStateChange();
}
onClick(value){
console.log('button clicked');
console.log('current this.value inside textbox component: ',this.value);
}
运行此测试时,文本框中的实际文本实际上是设置为“世界”,但组件中的formGroup实际值仍然是默认的“ hello”。我假设我跳过了一些触发ngModelChange
的事件。
我希望按键事件能够触发该事件,但是我编写的所有按键事件均未真正通过。我知道它们根本不会触发,因为不仅文本框内的文本保持默认值,而且我编写的侦听器根本不会触发。但是在物理按键之后,ngModelChange和我的事件侦听器都会执行。
Here's a screenshot of the results of the test immediately after running
其余部分是代码的其他部分。我认为它们无关紧要,但您可能比我更了解Angular哈哈
这是HTML Angular绑定的重要部分:
<div class="col-sm-9" [formGroup]="group"
><input
class="form-control"
[class.q-ngc-form-validation-border]="
control.errors && control.touched
"
[formControlName]="name"
[type]="type"
[id]="name"
[placeholder]="options.placeholder || ''"
(ngModelChange)="onValueChange($event)"
/>
<q-ngc-validation-text
*ngIf="control.touched"
[controlName]="name"
[label]="options.label"
[formControlErrors]="control.errors"
[formGroupErrors]="group.errors"
[asyncValidations]="asyncValidations"
></q-ngc-validation-text>
</div>
<button (click)="onClick(this.value)">Print current value</button>
这里是我设置组件的DynamicFormSpec:
const testTextInputForm: DynamicFormSpec = {
formName: 'testTextInputForm',formControlSpecs: [
{
name: 'textInputState',type: DynamicFormControlType.TEXT,valuePath: 'textInputState',options: {
label: 'Text Input Test',disabled: false
}
}
]
};
最后,这是我配置测试台的地方:
interface TestTextInputViewModel {
textInputState: string;
}
fdescribe('textInputComponent',() => {
let component: TestDynamicFormComponent<TestTextInputViewModel>;
let fixture: ComponentFixture<TestDynamicFormComponent<TestTextInputViewModel>>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [TestCoreFormsModule]
}).compileComponents();
fixture = TestBed.createComponent<
TestDynamicFormComponent<TestTextInputViewModel>
>(TestDynamicFormComponent);
component = fixture.componentInstance;
component.testDynamicFormSpec = cloneDeep(testTextInputForm);
component.viewModel = { textInputState: 'hello' };
fixture.detectChanges();
}));
任何有关如何实现模拟按键或在替换值后以编程方式触发(ngModelChange)
事件的其他方法的提示,将不胜感激!
非常感谢您!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。