简体   繁体   English

无法在单元测试案例中调用@HostListener方法

[英]Unable to invoke @HostListener method in the Unit Test case

I have created a custom Directive using @Directive in which I am using @HostListener and the code works fine. 我已经使用@Directive创建了一个自定义指令,其中我正在使用@HostListener并且代码可以正常工作。
Now, when writing the test case I need to invoke the @HostListener method from the unit test case. 现在,在编写测试用例时,我需要从单元测试用例中调用@HostListener方法。 Also I can see that in the code coverage the code is not covered. 我还可以看到在代码覆盖率中未覆盖代码。
Following is the code: 以下是代码:

focus-encapsulation.directive.ts 焦点封装指令

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[appFocusEncapsulation]'
})
export class FocusEncapsulationDirective {

  constructor(private el: ElementRef) { }

  @HostListener('keydown', ['$event'])
  keyDown(event: Event) {
    console.log('event : ', event);
    event.preventDefault();
  }

}

focus-encapsulation.directive.spec.ts 焦点封装指令规范

import { FocusEncapsulationDirective } from './focus-encapsulation.directive';
import { Component, ElementRef, DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from "@angular/platform-browser";

@Component({
  template: `<div appFocusEncapsulation><button type="button" (click)="add()">ADD</button></div>`
})
class TestHoverFocusComponent {
  constructor(private el: ElementRef) { 
    console.log('in constructor')
  }
}

fdescribe('FocusEncapsulationDirective', () => {

  let component: TestHoverFocusComponent;
  let fixture: ComponentFixture<TestHoverFocusComponent>;
  let inputEl: DebugElement;
  let elementRef: ElementRef

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [TestHoverFocusComponent, FocusEncapsulationDirective]
    });
    fixture = TestBed.createComponent(TestHoverFocusComponent);
    component = fixture.componentInstance;
    elementRef = fixture.nativeElement;
    inputEl = fixture.debugElement.query(By.css('button'));
  });

  it('should create an instance', () => {
    const directive = new FocusEncapsulationDirective(elementRef)
    expect(directive).toBeTruthy();
  });

  it('Focus over elements', () => {
    fixture.detectChanges();
    const event = {
      which : 9,
      keyCode : 9,
      srcElement :{
        innerText : 'ADD'
      },
      preventDefault: function() {
        console.log('preventDefault() method called');
      }
    }
    spyOn(event, 'preventDefault');
    inputEl.triggerEventHandler('keydown', event);
    expect(event.preventDefault()).toHaveBeenCalled();
  });

});

Below you can also see the code coverage report: 在下面您还可以查看代码覆盖率报告:
在此处输入图片说明

Here I need to cover the code and get the proper test case executed required for this method. 在这里,我需要覆盖代码并获取此方法所需的正确测试用例。 Thanks. 谢谢。

Here's a fixed version of your test: 这是测试的固定版本:

fdescribe('FocusEncapsulationDirective', () => {

  let fixture: ComponentFixture<TestHoverFocusComponent>;
  let inputEl: HTMLElement;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [TestHoverFocusComponent, FocusEncapsulationDirective]
    });
    fixture = TestBed.createComponent(TestHoverFocusComponent);
    inputEl = fixture.nativeElement.querySelector('button');
  });

  it('Focus over elements', () => {
    fixture.detectChanges();
    const event = new Event('keydown', { bubbles: true });
    spyOn(event, 'preventDefault');
    inputEl.dispatchEvent(event);
    expect(event.preventDefault).toHaveBeenCalled();
  });

});

Key points: 关键点:

  • you need to pass the spied function itself, to expect(), to check that it has been called. 您需要传递spied函数本身,以Expect()来检查它是否已被调用。 Your code calls the spied function, and passes what it returns to epect(). 您的代码将调用 spied函数,并将返回的内容传递给epect()。
  • You need to pass an actual event (and especially one that has its bubbles flag set to true, otherwise the event won't bubble, and the listener on the enclosing div will thus not be notified of the event triggered on the enclosed button) to the native DOM element . 您需要传递一个实际事件(尤其是将其bubbles标志设置为true的事件,否则该事件将不会冒泡,并且将不会向封闭div上的侦听器通知在封闭按钮上触发的事件)本机DOM元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM