我在 Angular 组件中有一个方法,可以通过选择给定某些条件的其中一张卡片来滚动元素列表(称为“卡片”),然后调用scrollIntoView() 方法。我尝试了多种方法来尝试通过单元测试(茉莉花框架)来覆盖此方法,但似乎无法弄清楚如何使其工作。任何意见将不胜感激!
方法如下:
scrollToCard() {
const scrollSlotToMatch = '10:00 - 11:00';
// Query the DOM to locate schedule card view elements that we want to choose from to scroll into view
const matches = Array.from(document.querySelectorAll('test-card'));
// Iterate through the card elements to find the appropriate one that matches the target scroll time
let selectedCard: HTMLElement | undefined;
for (let i = 0; i < matches.length; i++) {
const card = matches[i] as HTMLElement;
const cardInnerText = card.innerText.split('\n');
if (cardInnerText[0] === scrollSlotToMatch) {
selectedCard = card;
break;
}
}
// If we successfully located a card element, scroll it into view
if (selectedCard !== undefined) {
selectedCard.scrollIntoView();
}
}
在您的测试中,您可以获得
test-card
本机元素的列表,并迭代该列表,为每个元素的 scrollIntoView
方法创建一个间谍。将这些间谍收集到数组中后,您就可以根据其数组索引(与元素的索引相对应)来验证是否调用了正确的间谍。
因此,假设您正在测试的组件的模板包含
test-card
,如下所示:
<test-card content="8:00 - 9:00"></test-card>
<test-card content="9:00 - 10:00"></test-card>
<test-card content="10:00 - 11:00"></test-card>
<test-card content="11:00 - 12:00"></test-card>
你的测试看起来像这样:
it('scrolls the target element into view', () => {
const targetText = '10:00 - 11:00';
const expectedCardIndex = 2;
const cardDebugEls = fixture.debugElement.queryAll(By.css('test-card'));
const scrollSpies = cardDebugEls.map((cardDebugEl: DebugElement) => {
return spyOn(cardDebugEl.nativeElement, 'scrollIntoView').and.stub();
});
component.scrollToCard(targetText);
scrollSpies.forEach((spy: jasmine.Spy, index) => {
const expectedCallCount = index === expectedCardIndex ? 1 : 0;
expect(spy.calls.count()).toBe(expectedCallCount);
});
});
这里有一个 StackBlitz 展示了这种方法。