使用事件发射器测试可点击的 Angular 指令 - @Output() 未引发/触发

Testing a clickable Angular Directive with an Event Emitter - @Output() isn't raised / fired

我有一个小指令,可以检测用户是否在指令附加到的 HTML 元素之外单击,它看起来像这样,没什么特别的:

@Directive({
  selector: '[vcrClickOutside]'
})
export class ClickOutsideDirective {

  constructor(private elementRef: ElementRef) { }

  @Output()
  clickOutside = new EventEmitter();

  @HostListener('document:click', ['$event.target'])
  onClick(targetElement): void {
    const clickedInside = this.elementRef.nativeElement.contains(targetElement);
    if (!clickedInside) {
      this.clickOutside.emit(targetElement);
    }
  }
}

现在是测试我的指令的时候了,所以我创建了一个测试文件,引入了一个 Mock 组件,附加了指令,在我的测试中,我单击了 Mock 组件的模板并尝试捕获发射器,这是测试:

// Mock Component
@Component({
  template: '<div (clickOutside)="toggleClick($event)"><div vcrClickOutside>Oh I just love writing tests</div></div>'
})
class MockComponent {
  constructor() { }
  hasBeenClicked = false;
  toggleClick(ev): void {
    this.hasBeenClicked = !this.hasBeenClicked;
  }
}
describe('ClickOutsideDirective', () => {

  let component: MockComponent;
  let fixture: ComponentFixture<MockComponent>;
  let element: HTMLElement;
  let outSideDiv: HTMLElement;
  let insideDiv: HTMLElement;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        MockComponent,
        ClickOutsideDirective
      ]
    });

    fixture = TestBed.createComponent(MockComponent);
    component = fixture.componentInstance;
    element = fixture.debugElement.nativeElement;
    outSideDiv = element.querySelectorAll('div')[0];
    insideDiv = element.querySelectorAll('div')[1];
    fixture.detectChanges();
  });

  it('click the outer div thus emitting the clickOutside and toggle the component value', () => {
    outSideDiv.click();
    fixture.detectChanges();
    expect(component.hasBeenClicked).toBeTruthy();
  });

一切似乎都很好,但是当我点击外部 div 时,即使我知道指令正在发出外部 div 上的 @Output 也没有被引发,所以查看代码 (clickOutside) 未被调用,因此方法 toggleClick($event) 不是 运行,我做错了什么?

*** 更新 ****

我的输出就错了div!我是个白痴!

正如我在评论中的回答 - 我把发射器放在了错误的位置!

@Component({
  template: '<div><div vcrClickOutside (clickOutside)="toggleClick($event)">Oh I just love writing tests</div></div>'
})