在 Angular Jest 测试中模拟窗口、文档和鼠标单击事件属性



>我有一个附加到偶数侦听器的函数,该函数检查您是否单击了弹出窗口或其中,并在单击它时将其关闭。它使用窗口和文档对象上的各种属性来检查这些内容,以及getBoundingClientRect()来获取弹出窗口的位置。

我遇到的问题是我无法弄清楚如何在测试中模拟所有这些。我看到在 Jest 中你在模拟事物时使用全局对象作为窗口对象?

这是我检查定位和单击的函数:

popoverEscape = e => {
const popover = this.panelEl.nativeElement.getBoundingClientRect();
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const left = popover.left + scrollLeft
const right = popover.left + scrollLeft + popover.width
const top = popover.top + scrollTop
const bottom = popover.top + scrollTop + popover.height
if(!this.isBetween(e.clientX, left, right) || !this.isBetween(e.clientY, top, bottom)){
this.closePopover()

}
};
isBetween(n, a, b) {
return (n - a) * (n - b) <= 0
}

下面是单元测试解决方案:

index.ts

export class SomeComponent {
panelEl = {
nativeElement: document.createElement('div'),
};
popoverEscape = (e) => {
const popover = this.panelEl.nativeElement.getBoundingClientRect();
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const left = popover.left + scrollLeft;
const right = popover.left + scrollLeft + popover.width;
const top = popover.top + scrollTop;
const bottom = popover.top + scrollTop + popover.height;
if (!this.isBetween(e.clientX, left, right) || !this.isBetween(e.clientY, top, bottom)) {
this.closePopover();
}
};
isBetween(n, a, b) {
return (n - a) * (n - b) <= 0;
}
closePopover() {}
}

index.test.ts

import { SomeComponent } from './';
describe('59737707', () => {
afterEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});
describe('#popoverEscape', () => {
it('should close popover if first isBetween return falsy', () => {
Object.defineProperty(window, 'pageXOffset', { value: 100 });
document.documentElement.scrollTop = 200;
const comp = new SomeComponent();
const rect = { left: 10, width: 20, top: 10, height: 50 };
jest.spyOn(comp.panelEl.nativeElement, 'getBoundingClientRect').mockReturnValueOnce(rect as DOMRect);
jest.spyOn(comp, 'isBetween').mockReturnValueOnce(false);
comp.closePopover = jest.fn();
const mEvent = { clientX: 100, clientY: 200 };
comp.popoverEscape(mEvent);
expect(comp.panelEl.nativeElement.getBoundingClientRect).toBeCalledTimes(1);
expect(comp.closePopover).toBeCalledTimes(1);
expect(comp.isBetween).toBeCalledTimes(1);
});
it('should close popover if second isBetween return falsy', () => {
Object.defineProperty(window, 'pageXOffset', { value: 100 });
document.documentElement.scrollTop = 200;
const comp = new SomeComponent();
const rect = { left: 10, width: 20, top: 10, height: 50 };
jest.spyOn(comp.panelEl.nativeElement, 'getBoundingClientRect').mockReturnValueOnce(rect as DOMRect);
jest
.spyOn(comp, 'isBetween')
.mockReturnValueOnce(true)
.mockReturnValueOnce(false);
comp.closePopover = jest.fn();
const mEvent = { clientX: 100, clientY: 200 };
comp.popoverEscape(mEvent);
expect(comp.panelEl.nativeElement.getBoundingClientRect).toBeCalledTimes(1);
expect(comp.closePopover).toBeCalledTimes(1);
expect(comp.isBetween).toBeCalledTimes(2);
});
});
});

带有覆盖率报告的单元测试结果:

PASS  src/stackoverflow/59737707/index.test.ts (14.308s)
59737707
#popoverEscape
✓ should close popover if first isBetween return falsy (12ms)
✓ should close popover if second isBetween return falsy (3ms)
----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |    94.12 |       75 |       50 |    93.75 |                   |
index.ts |    94.12 |       75 |       50 |    93.75 |                21 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        16.602s

您可以对未覆盖的分支和功能执行相同的操作,并将测试覆盖率提高到 100%。

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59737707

最新更新