[英]How test directive with Renderer2?
我創建了一個小指令,以防止傳遞給它的默認事件。
@Directive({
selector: '[sPreventDefault]'
})
export class PreventDefaultDirective {
private events: (() => void)[] = [];
@Input('sPreventDefault') set listenOn(events: string | string[]) {
this.removeListeners();
if (typeof events == 'string') {
events = [events];
}
this.registerEventListener(
events,
e => {
if (e instanceof Event) {
e.stopPropagation();
} else {
e.srcEvent.stopPropagation();
}
},
);
}
constructor(private elementRef: ElementRef<HTMLElement>, private renderer: Renderer2) {
super(elementRef, renderer);
}
protected registerEventListener(listenOn: string[], eventListener: (e: Event | HammerJSEvent) => void): void {
this.events = listenOn.map(eventName => {
return this.renderer.listen(this.elementRef.nativeElement, eventName, eventListener);
});
}
protected removeListeners(): void {
this.events.forEach(dispose => dispose());
this.events = [];
}
}
測試服
@Component({
selector: 'test-host',
template: `<div [sPreventDefault]="events">`,
})
class TestHostComponent {
@ViewChild(PreventDefaultDirective) directive!: PreventDefaultDirective;
@Input() events: PreventDefaultDirective['listenOn'] = [];
}
fdescribe('PreventDefaultDirective', () => {
let host: TestHostComponent;
let hostElement: DebugElement;
let fixture: ComponentFixture<TestHostComponent>;
let directive: PreventDefaultDirective;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
TestHostComponent,
PreventDefaultDirective,
],
}).compileComponents();
fixture = TestBed.createComponent(TestHostComponent);
hostElement = fixture.debugElement;
host = fixture.componentInstance;
directive = host.directive;
}));
it('should create an instance', () => {
host.events = ['testEvent'];
fixture.detectChanges();
expect(directive).toBeTruthy();
});
it('should add listener', () => {
host.events = ['testEvent'];
fixture.detectChanges();
// DebugElement.listeners is null
expect(hostElement.listeners.length).toBe(1);
expect(hostElement.listeners.map(l => l.name)).toBe(host.events);
});
});
我的問題是, DebugElement
似乎不了解通過Renderer2.listen
方法注冊的事件。 什么是正確的測試方法?
好吧,自從有興趣以來,我檢查了一些事情,盡管您可以找到有用的東西,但它不是直截了當的答案,甚至也無法解決您的問題。
看起來hostElement.listeners
指向@HostListener
裝飾器添加的事件偵聽器,您可以輕松地進行檢查。 我也嘗試尋找方法來檢索偵聽器,但沒有成功。
我在這里要做的是檢查何時調用renderer.listen
並把實現留在后面-這種方式對於高於“單元測試”的測試可能是錯誤的,因為您要檢查這是否確實有效,但對於單元來說應該沒問題。 如果要監視Renderer2
,可以執行以下操作:
const renderer = fixture.componentRef.injector.get(Renderer2);
const listenSpy = spyOn(renderer, 'listen');
expect(listenSpy).toHaveBeenCalled();
編輯1:由於不建議使用提供Renderer2
方式,因此應使用:
const renderer = fixture.componentRef.injector.get(Renderer2 as Type<Renderer2>);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.