I have this directive but Im struggling with the jasmine test for it, any ideas?
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();
}
}
Usually with directives, I just attach it to a dummy component/HTML element and test from there. I am going all without an IDE so there may be some mistakes.
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 https://stackoverflow.com/a/40282709/7365461)
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();
});
});
I got inspired with the dispatchEvent from here: https://johngrahamdev.com/Unit-Testing-Keyboard-Shortcuts-Angular/