Макет документа для шутливого тестирования - PullRequest
1 голос
/ 14 мая 2019

У меня есть такая функция внутри реагирующего компонента:

    handleOnScroll = () => {
        const {navigationSections, setNavigationSectionActive} = this.props;

        const reversedSections = this.getReversedNavigationSections();

        const OFFSET_TOP = 32;
        const st = window.pageYOffset || document.documentElement.scrollTop; 

        if (st > lastScrollTop) {
            for (let i = 0; i < navigationSections.length; i += 1) {
                if(document.getElementById(navigationSections[i].id).getBoundingClientRect().top <= OFFSET_TOP) {
                    setNavigationSectionActive(navigationSections[i].id);
                }
            }

        } else if (st < lastScrollTop) {
            for (let y = 0; y < reversedSections.length; y += 1) {
                if(document.getElementById(navigationSections[y].id).getBoundingClientRect().top <= OFFSET_TOP) {
                    setNavigationSectionActive(navigationSections[y].id);
                }
            }
        }

        lastScrollTop = st <= 0 ? 0 : st;

    }

, а некоторые тесты примерно такие:

    it('should handle handleOnScroll', () => {
        instance.handleOnScroll();
        expect(instance.getReversedNavigationSections()).toEqual(props.navigationSections.reverse());
    });

    props.navigationSections.forEach(navSection => {
        it('should call setNavigationSectionActive', () => {
            instance.handleOnScroll();
            expect(props.setNavigationSectionActive).toHaveBeenCalledWith(navSection.id);
        });
    });

первый тест проходит, но второй ('следует вызвать setNavigationSectionActive '), как вы видите, не удается:

enter image description here

Я думаю, что причина в том, что документ не является поддельным, поэтому происходит сбой if.Однако в реальной реализации, когда это выполняется:

document.getElementById(navigationSections[i].id).getBoundingClientRect().top 

DIV, которые имеют эти идентификаторы, находятся в другом разделе (не в компоненте-обертке, используемом для рассматриваемого теста).

я должен издеваться над документом, чтобы имитировать фактическую структуру для утверждения if, или я совершенно не прав?

МОЯ ПОПЫТКА ТАК ДАЛЬШЕ

    it('should handle custom handleOnScroll', () => {
        document.body.innerHTML = '<div><div id="id">my div</div><div id="id-1">my div</div></div>';

        const div = document.getElementById('id');
        div.getBoundingClientRect = () => ({ top: 100 });  // <= mock getBoundingClientRect
        instance.handleOnScroll();
        props.navigationSections.forEach(() => {
            if (global.document.getElementById('id').getBoundingClientRect().top <= global.OFFSET_TOP) {
                expect(props.setNavigationSectionActive).toHaveBeenCalledWith('id');
            }
        });
    });

1 Ответ

2 голосов
/ 14 мая 2019

Средой тестирования по умолчанию для Jest является jsdom, которая обеспечивает среду, подобную браузеру.

Если для вашего теста требуется определенный контент в document, вы можете установить тело документа, используя что-то вродеdocument.body.innerHTML.

jsdom реализует множество функций браузера, но не все.В этом случае getBoundingClientRect заглушается, чтобы всегда возвращать 0, поэтому, если вы хотите, чтобы он возвращал что-то еще, вам придется высмеивать это.

Вот простой рабочий пример, чтобы вы начали:

const OFFSET_TOP = 5;

const func = () => 
  document.getElementById('theid').getBoundingClientRect().top <= OFFSET_TOP ?
    'less' :
    'more';

test('func', () => {
  document.body.innerHTML = '<div id="theid">my div</div>';
  expect(func()).toBe('less');  // Success!

  const div = document.getElementById('theid');
  div.getBoundingClientRect = () => ({ top: 10 });  // <= mock getBoundingClientRect
  expect(func()).toBe('more');  // Success!
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...