Попытка издеваться над setInterval() в шутку, используя jest.useFakeTimers(),работает не так, как ожидалось, и утверждения приводят к ошибкам сопоставления типов

#javascript #typescript #testing #jestjs

Вопрос:

Я прочитал все сообщения здесь, а также документацию по шуткам, но, похоже, я все еще делаю что-то не так. Я пишу модульные тесты для службы, которая использует глобальную функцию setInterval (). Когда я пишу тест, я продолжаю получать следующую ошибку:

 expect(received).toHaveBeenCalledTimes(expected)

    Matcher error: received value must be a mock or spy function

    Received has type:  function
    Received has value: [Function anonymous]

      40 |
      41 |     expect(smartlook).toHaveBeenCalledTimes(2);
    > 42 |     expect(setInterval).toHaveBeenCalledTimes(1);
         |                         ^
      43 |   });
      44 | });
 

Вот функция:

 /**
 * trackSmartlook
 */
function trackSmartlook( eventType: string, eventName: string, properties = false ): void {
  if (window.smartlook) {
    window.smartlook.apply([eventType, eventName, properties]);
  } else {
    const checkSmartlookLoaded = setInterval(() => {
      if (window.smartlook) {
        window.smartlook.apply([eventType, eventName, properties]);
        clearInterval(checkSmartlookLoaded);
      }
    }, 1000);
  }
}

export default trackSmartlook;
 

А вот тестовый файл:

 import trackSmartlook from 'Services/app/SmartlookService';

const eventType      = 'track';
const eventName      = 'event name';

/**
 * Mocking window.smartlook
 */
Object.defineProperty(window, 'smartlook', {
  value   : jest.fn().mockImplementation(),
});

beforeEach(() => {
  jest.useFakeTimers();
});

afterEach(() => {
  jest.runOnlyPendingTimers();
  jest.useRealTimers();
});

/**
 * Test SmartlookService
 */
describe('test SmartlookService', () => {
  it ('trackSmartlook calls setInterval and call window.smartlook twice', () => {
    const smartlook = jest.spyOn(window,'smartlook').mockImplementation();
    smartlook.mockReturnValue(undefined);

    trackSmartlook(eventName, eventType);

    jest.advanceTimersByTime(1001);

    expect(smartlook).toHaveBeenCalledTimes(2);
    expect(setInterval).toHaveBeenCalledTimes(1);
  });
});

 

Я перепробовал все, что предлагается в документации Jest. Т. е. jest. spyOn(глобальный, «сетИнтервал»), jest.useFakeTimers («наследие») и т. Д., Но все равно получаю тот же результат. Любые предложения будут оценены по достоинству. Шутка версии 27.0.1

Комментарии:

1. Пожалуйста, проверьте ссылку ниже, если это может вам помочь : medium.com/@chris.marshall/…

Ответ №1:

Попробуйте использовать jest.useFakeTimers('legacy')

Комментарии:

1. Я сделал, все то же самое

2. Это заставило его работать на v27.0.5 для меня. Возможно, вы захотите попробовать обновить

3. Я обновил и и все та же ошибка, действительно странно.