使用事件发射器测试可点击的 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>'
})
我有一个小指令,可以检测用户是否在指令附加到的 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>'
})