Как шпионить, была ли функция использована или нет с модульным тестированием Jest для javascript?

Когда я пытаюсь установить шпиона для импортированной функции, я получаю следующую ошибку msg TypeError: Невозможно прочитать свойство '_isMockFunction' из неопределенного

Я не понимаю, что не так с этим кодом

Импортированная функция как ниже здесь экспорт

export
function myFn(){
    let htmlEl = document.querySelector('html');
    let el = document.querySelector('.target-el');
    if(el){
        el.addEventListener('click', myInternalFn, false);
    }

    function myInternalFn () {
        isUserLoggedIn((isIn) => {
            let logoutClassName = 'el--logout';
            if (isIn) {
                el.classList.remove(logoutClassName);
                return;
            } 
            el.classList.add(logoutClassName);
        });
    }

    function isUserLoggedIn (fn) {
        return fn(localStorage.getItem('userLoggedIn') === 'true');
    }
}

document.addEventListener('DOMContentLoaded', () => {
    myFn();
});

TDD:

    import { betSlip } from "../src/main/javascript/custom/betslip-dialog";

    describe('Testing bet slip button (only on mobile)', function () {
         let htmlEl;
         let el;

         beforeEach(() => {
            document.body.innerHTML =
            `
            <html>
                <div class="target-el"></div>
            </html>
            `;

            myFn();
            htmlEl = document.querySelector('html');


        });

        it('When el button has been clicked for the first time', done => {
          jest.spyOn(myFn, 'myInternalFn');
          myInternalFn.click();
          expect(true).toBe(true);

          done();
        });

    });

1 ответ

Решение

Согласно документации Jest https://facebook.github.io/jest/docs/en/jest-object.html в вашем коде

jest.spyOn(myFn, 'myInternalFn');

myFn должен быть объектом и myInternalFn должен быть свойством этого объекта. В текущей реализации myInternalFn спрятан в myFnсфера, и не подвергается воздействию извне. Я предлагаю вам переписать код (если это возможно) для использования любого прототипа:

myFn.prototype.myInternalFn = function myInternalFn () { ... }

//and in tests
jest.spyOn(myFn.prototype, 'myInternalFn');

или прямое присвоение объекту функции (не самый лучший способ для меня)

myFn.myInternalFn = function myInternalFn () { ... }

// and in tests
jest.spyOn(myFn, 'myInternalFn');

Основная идея - без публичного разоблачения myInternalFn ты не можешь повесить на нее шпиона.

Другие вопросы по тегам