用茉莉花测试指令

testing directive with jasmine

我有这个指令,但我正在为它做 jasmine 测试,有什么想法吗?

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

@Directive({
   selector: '[ctrlKeys]',
})
export class CtrlKeysDirective {
   @Output() ctrlZ = new EventEmitter();
   @Output() ctrlY = new EventEmitter();

   @HostListener('document:keydown.control.z') onCtrlZ() {
       this.ctrlZ.emit();
   }

   @HostListener('document:keydown.control.y') onCtrlY() {
       this.ctrlY.emit();
   }
}

通常使用指令,我只是将它附加到一个虚拟 component/HTML 元素并从那里进行测试。我完全没有 IDE 所以可能会有一些错误。

describe('CtrlKeysDirective', () => {
  @Component({
    selector: 'dummy',
    template: `<div class="under-test" ctrlKeys>Hello</div>`
  })
  class DummyComponent {}
  
  let fixture: ComponentFixture<DummyComponent>;
  let component: DummyComponent;
  let ctrlKeysDirective: CtrlKeysDirective;

  beforeEach(waitForAsync(() => {
   TestBed.configureTestingModule({
     // declare both your directive and dummy component
     declarations: [DummyComponent, CtrlKeysDirective],
   }).compileComponents();
  }));

  beforeEach(() => {
    // get a handle on your component
    fixture = TestBed.createComponent(DummyComponent);
    component = fixture.componentInstance;
    // call ngOnInit of the component (not required)
    fixture.detectChanges();
    // get a handle on your directive (inspired from here 
    const ctrlKeysDirectiveEls = fixture.debugElement.query(By.directive(CtrlKeysDirective));
    ctrlKeysDirective = ctrlKeysDirectiveEls[0].injector.get(CtrlKeysDirective) as CtrlKeysDirective;
  });

  it('should create', () => {
    // expect the component to be truthy. Make sure this test passes to ensure
   // the TestBed was configured correctly.
    expect(component).toBeTruthy();
  });

  it('should emit ctrlZ', () => {
    const ctrlZSpy = spyOn(ctrlKeysDirective.ctrlZ, 'emit');
    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'z', ctrlKey: true }));
    // !! try this !!
    const div = fixture.debugElement.query(By.css('.under-test')).nativeElement;
    div.dispatchEvent(new KeyboardEvent('keydown', { key: 'z', ctrlKey: true }));
    fixture.detectChanges();
    expect(ctrlZSpy).toHaveBeenCalled();
  });
});

我从这里的 dispatchEvent 获得灵感:https://johngrahamdev.com/Unit-Testing-Keyboard-Shortcuts-Angular/