如何为在 HTML 元素上调用scrollIntoView 的代码创建单元测试

问题描述 投票:0回答:1

我在 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();
    }
  }
angular typescript unit-testing jasmine
1个回答
0
投票

在您的测试中,您可以获得

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 展示了这种方法。

© www.soinside.com 2019 - 2024. All rights reserved.