无法理解为什么这个 Jasmine 测试一直失败并出现队列中的计时器错误
Unable to understand why this Jasmine test keeps failing with a timer in queue error
我正在尝试测试以下使用 RxJS 向订阅者广播长按事件的函数
export function watchForLongPress(target: HTMLElement) {
let timer: number;
const notifier = new Subject<PointerEvent>();
const pointerdown = (event: PointerEvent) => {
timer = window.setTimeout(() => notifier.next(event), 500);
};
const pointerup = () => {
window.clearTimeout(timer);
};
target.addEventListener('pointerdown', pointerdown, false);
window.addEventListener('pointerup', pointerup, false);
return notifier.asObservable().pipe(finalize(() => {
target.removeEventListener('pointerdown', pointerdown, false);
window.removeEventListener('pointerup', pointerup, false);
}));
}
下面是确保如果用户长按少于 500 毫秒不会广播任何事件的测试,但 Jasmine 一直失败 Error: 1 timer(s) still in the queue.
但我不明白为什么。我使用 Karma 作为测试运行器,Jasmine 作为断言库
describe('#watchForLongPress', () => {
// This test passes
it('1. should emit after pressing on target for 500ms or longer', fakeAsync(() => {
const target = document.createElement('button');
const longPressListenerSpy = jasmine.createSpy('longPressListenerSpy');
watchForLongPress(target).subscribe({
next: longPressListenerSpy
});
target.dispatchEvent(new Event('pointerdown'));
tick(600);
target.dispatchEvent(new Event('pointerup'));
expect(longPressListenerSpy).toHaveBeenCalledTimes(1);
}));
// While this test keeps failing with `Error: 1 timer(s) still in the queue.`
it('2. should not emit if pressing on target for less than 500ms', fakeAsync(() => {
const target = document.createElement('button');
const longPressListenerSpy = jasmine.createSpy('longPressListenerSpy');
watchForLongPress(target).subscribe({
next: longPressListenerSpy
});
target.dispatchEvent(new Event('pointerdown'));
tick(300);
target.dispatchEvent(new Event('pointerup'));
expect(longPressListenerSpy).toHaveBeenCalledTimes(0);
}));
});
对于测试 #2,我只是将 target.dispatchEvent(new Event('pointerup'));
更改为 window.dispatchEvent(new Event('pointerup'));
,因为在我的 watchForLongPress
函数中,我将 pointerup
附加到 window
,而不是target
,即使执行 target.dispatchEvent(new Event('pointerup', { bubbles: true }));
仍然不会在测试环境中使分派的事件冒泡到 window
。
我正在尝试测试以下使用 RxJS 向订阅者广播长按事件的函数
export function watchForLongPress(target: HTMLElement) {
let timer: number;
const notifier = new Subject<PointerEvent>();
const pointerdown = (event: PointerEvent) => {
timer = window.setTimeout(() => notifier.next(event), 500);
};
const pointerup = () => {
window.clearTimeout(timer);
};
target.addEventListener('pointerdown', pointerdown, false);
window.addEventListener('pointerup', pointerup, false);
return notifier.asObservable().pipe(finalize(() => {
target.removeEventListener('pointerdown', pointerdown, false);
window.removeEventListener('pointerup', pointerup, false);
}));
}
下面是确保如果用户长按少于 500 毫秒不会广播任何事件的测试,但 Jasmine 一直失败 Error: 1 timer(s) still in the queue.
但我不明白为什么。我使用 Karma 作为测试运行器,Jasmine 作为断言库
describe('#watchForLongPress', () => {
// This test passes
it('1. should emit after pressing on target for 500ms or longer', fakeAsync(() => {
const target = document.createElement('button');
const longPressListenerSpy = jasmine.createSpy('longPressListenerSpy');
watchForLongPress(target).subscribe({
next: longPressListenerSpy
});
target.dispatchEvent(new Event('pointerdown'));
tick(600);
target.dispatchEvent(new Event('pointerup'));
expect(longPressListenerSpy).toHaveBeenCalledTimes(1);
}));
// While this test keeps failing with `Error: 1 timer(s) still in the queue.`
it('2. should not emit if pressing on target for less than 500ms', fakeAsync(() => {
const target = document.createElement('button');
const longPressListenerSpy = jasmine.createSpy('longPressListenerSpy');
watchForLongPress(target).subscribe({
next: longPressListenerSpy
});
target.dispatchEvent(new Event('pointerdown'));
tick(300);
target.dispatchEvent(new Event('pointerup'));
expect(longPressListenerSpy).toHaveBeenCalledTimes(0);
}));
});
对于测试 #2,我只是将 target.dispatchEvent(new Event('pointerup'));
更改为 window.dispatchEvent(new Event('pointerup'));
,因为在我的 watchForLongPress
函数中,我将 pointerup
附加到 window
,而不是target
,即使执行 target.dispatchEvent(new Event('pointerup', { bubbles: true }));
仍然不会在测试环境中使分派的事件冒泡到 window
。