Angular 测试角度指令
我有一个附加到元素上的事件的角度指令:Angular 测试角度指令,angular,unit-testing,karma-jasmine,angular-directive,Angular,Unit Testing,Karma Jasmine,Angular Directive,我有一个附加到元素上的事件的角度指令: @Directive({ selector: '[myDirective]' }) export class MyDirective { @HostListener('click', ['$event']) click(event: Event): void { debugger; console.log(event); // <-- this is null in unit tests, MouseE
@Directive({
selector: '[myDirective]'
})
export class MyDirective {
@HostListener('click', ['$event']) click(event: Event): void {
debugger;
console.log(event); // <-- this is null in unit tests, MouseEvent when running the app normally
}
}
现在,问题是:指令在单元测试中被命中,但没有作为参数发送的事件
我遵循了这个示例:但不幸的是,它没有使用事件参数
编辑
我还按照下面的步骤将参数传递给@HostListener()
装饰器:
@HostListener('mouseenter', ['$event.target.id'])
onMouseEnter(id: string) {
// Logs the id of the element
// where the event is originally invoked.
console.log(id);
}
编辑2
从DebugElement引发的事件似乎并不真正代表来自DOM元素的实际事件侦听器
根据Hojou所说,如果你从nativeElement触发事件,它就会工作。因此,下面的代码确实通过事件发送到指令,只是不太确定它是否正确:
describe(`should listen to the events`, () => {
it(`should listen to the click event`, () => {
// fixture.triggerEventHandler('click', null);
debugElement.nativeElement.dispatchEvent(newEvent('click'));
fixture.detectChanges();
// expect...
});
});
function newEvent(eventName: string) {
const customEvent: CustomEvent<any> = document.createEvent('CustomEvent'); // MUST be 'CustomEvent'
customEvent.initCustomEvent(eventName, false, false, null);
return customEvent;
}
description(`should-listen-to-events`,()=>{
它(`应该监听点击事件',()=>{
//fixture.triggerEventHandler('click',null);
debugElement.nativeElement.dispatchEvent(newEvent('click'));
fixture.detectChanges();
//期待。。。
});
});
函数newEvent(eventName:string){
const customEvent:customEvent=document.createEvent('customEvent');//必须是'customEvent'
initCustomEvent(eventName,false,false,null);
返回自定义事件;
}
您在那里得到的是null,因为您将null
作为参数传递到
fixture..triggerEventHandler('click', null);
我认为这是一个打字错误,应该是
debugElement.triggerEventHandler('click', null);
如果您将一个对象传递到那里,您将看到它被记录在指令中
debugElement.triggerEventHandler('click', {test: 'test'});
我想补充一点,我个人会通过“执行”实际DOM对象上的单击来进行此测试,因此您不需要自己指定/存根事件,这似乎有助于进行更可靠的测试
因此,您不必使用triggerEventHandler
行,而是执行以下操作
debugElement.nativeElement.click()
您在那里得到null,因为您在中作为参数传递
null
fixture..triggerEventHandler('click', null);
我认为这是一个打字错误,应该是
debugElement.triggerEventHandler('click', null);
如果您将一个对象传递到那里,您将看到它被记录在指令中
debugElement.triggerEventHandler('click', {test: 'test'});
我想补充一点,我个人会通过“执行”实际DOM对象上的单击来进行此测试,因此您不需要自己指定/存根事件,这似乎有助于进行更可靠的测试
因此,您不必使用triggerEventHandler行,而是执行以下操作
debugElement.nativeElement.click()
在编辑2中,引发一个自定义事件,并通过指令的附加元素发送
debugElement.triggerEventHandler('click', {test: 'test'});
根据Hojou所说的,如果你从nativeElement触发事件,它就会起作用。因此,下面的代码确实通过事件发送到指令,只是不太确定它是否正确:
describe(`should listen to the events`, () => {
it(`should listen to the click event`, () => {
// fixture.triggerEventHandler('click', null);
debugElement.nativeElement.dispatchEvent(newEvent('click'));
fixture.detectChanges();
// expect...
});
});
function newEvent(eventName: string) {
const customEvent: CustomEvent<any> = document.createEvent('CustomEvent'); // MUST be 'CustomEvent'
customEvent.initCustomEvent(eventName, false, false, null);
return customEvent;
}
description(`should-listen-to-events`,()=>{
它(`应该监听点击事件',()=>{
//fixture.triggerEventHandler('click',null);
debugElement.nativeElement.dispatchEvent(newEvent('click'));
fixture.detectChanges();
//期待。。。
});
});
函数newEvent(eventName:string){
const customEvent:customEvent=document.createEvent('customEvent');//必须是'customEvent'
initCustomEvent(eventName,false,false,null);
返回自定义事件;
}
在编辑2中,引发一个自定义事件,并通过指令的附加元素发送
debugElement.triggerEventHandler('click', {test: 'test'});
根据Hojou所说的,如果你从nativeElement触发事件,它就会起作用。因此,下面的代码确实通过事件发送到指令,只是不太确定它是否正确:
describe(`should listen to the events`, () => {
it(`should listen to the click event`, () => {
// fixture.triggerEventHandler('click', null);
debugElement.nativeElement.dispatchEvent(newEvent('click'));
fixture.detectChanges();
// expect...
});
});
function newEvent(eventName: string) {
const customEvent: CustomEvent<any> = document.createEvent('CustomEvent'); // MUST be 'CustomEvent'
customEvent.initCustomEvent(eventName, false, false, null);
return customEvent;
}
description(`should-listen-to-events`,()=>{
它(`应该监听点击事件',()=>{
//fixture.triggerEventHandler('click',null);
debugElement.nativeElement.dispatchEvent(newEvent('click'));
fixture.detectChanges();
//期待。。。
});
});
函数newEvent(eventName:string){
const customEvent:customEvent=document.createEvent('customEvent');//必须是'customEvent'
initCustomEvent(eventName,false,false,null);
返回自定义事件;
}
您不直接测试指令。您可以通过一个测试组件来测试它们。这里我正在测试这里描述的*ngVar指令-
这里的主要优点是测试指令时,只需使用与测试组件完全相同的方法。测试指令的行为是基于测试组件做它应该做的事情
从“/ng-var.directive”导入{NgVarDirective};
从'@angular/core'导入{Component,DebugElement};
从“@angular/core/testing”导入{ComponentFixture,TestBed};
从“../directives.module”导入{DirectivesModule};
从“@angular/platform browser”导入{By}”;
@组成部分({
模板:“{myVar}}”
})
类TestComponent{}
描述('NgVarDirective',()=>{
let组件:TestComponent;
let夹具:组件夹具;
在每个之前(()=>{
TestBed.configureTestingModule({
声明:[TestComponent],
导入:[DirectivesModule]
});
fixture=TestBed.createComponent(TestComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
});
它('应该创建',()=>{
expect(component.toBeTruthy();
});
它('应该创建一个实例(HTMLElement)',()=>{
const el:HTMLElement=fixture.debugElement.nativeElement;
常量div:htmldevelement=el.querySelector('div');
expect(div.textContent).toBe('42');
});
它('应该创建一个实例(DebugElement)',()=>{
const el:DebugElement=fixture.DebugElement;
const de:DebugElement=el.query(By.css('div');
expect(de.nativeElement.textContent).toBe('42');
});
});
这里的另一个示例(与上面的示例不同,它不测试结构指令)您不直接测试指令。你可以通过一个测试组件来测试它们