Jest модульный тест для функции debounce - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь написать модульный тест для функции debounce. Мне трудно думать об этом.

Это код:

function debouncer(func, wait, immediate) {
  let timeout;

  return (...args) => {
    clearTimeout(timeout);

    timeout = setTimeout(() => {
      timeout = null;
      if (!immediate) func.apply(this, args);
    }, wait);

    if (immediate && !timeout) func.apply(this, args);
  };
}

Как начать?

Ответы [ 4 ]

0 голосов
/ 06 мая 2019

Не уверен, как это будет работать с шуткой, так как я использую мокко, но для всех, кто ищет простое решение:

it('debounce.spec', done => {
    // Arrange
    const log = sinon.spy();
    const search = debounce(log, 100);

    // Act
    search();

    // Assert
    setTimeout(() => {
      expect(log.called).to.be.true;
      done();
    }, 100);
  });
0 голосов
/ 07 декабря 2018

На самом деле, вам не нужно использовать Sinon для тестирования отказов. Jest может издеваться над всеми таймерами в коде JS.

Проверьте следующий код (это TypeScript, но вы можете легко перевести его на JS):

import * as _ from 'lodash';

// tell jest to mock all timeout functions
jest.useFakeTimers();

describe('debounce', () => {

    let func: jest.Mock;
    let debouncedFunc: Function;

    beforeEach(() => {
        func = jest.fn();
        debouncedFunc = _.debounce(func, 1000);
    });

    test('execute just once', () => {
        for (let i = 0; i < 100; i++) {
            debouncedFunc();
        }

        // fast-forward time
        jest.runAllTimers();

        expect(func).toBeCalledTimes(1);
    });
});

Дополнительная информация: https://jestjs.io/docs/en/timer-mocks.html

0 голосов
/ 08 января 2019

Если в вашем коде вы делаете это:

import debounce from 'lodash/debounce';

myFunc = debounce(myFunc, 300);

и вы хотите проверить функцию myFunc или функцию, вызывающую ее, затем в своем тесте вы можете смоделировать реализацию debounce, используя jest, чтобы она просто возвращала вашу функцию:

import debounce from 'lodash/debounce';

// Tell jest to mock this import
jest.mock('lodash/debounce');

it('my test', () => {
    // ...
    debounce.mockImplementation(fn => fn); // Assign the import a new implementation, in this case it's execute the function given to you
    // ...
});

Источник: https://gist.github.com/apieceofbart/d28690d52c46848c39d904ce8968bb27

0 голосов
/ 07 сентября 2018

Возможно, вы захотите проверить логику в своей функции debouncer:

Сказав это, звучит так, как будто ваш реальный вопрос касается тестирования неисправных функций.

Проверка исправленных функций

Вы можете проверить, отменяется ли функция, используя макет для отслеживания вызовов функций и фальшивые таймеры для имитации времени.

Вот простой пример использования Jest фиктивной функции и Sinon фальшивых таймеров функции, отклоненной с помощью debounce() из Lodash:

const _ = require('lodash');
import * as sinon from 'sinon';

let clock;

beforeEach(() => {
  clock = sinon.useFakeTimers();
});

afterEach(() => {
  clock.restore();
});

test('debounce', () => {
  const func = jest.fn();
  const debouncedFunc = _.debounce(func, 1000);

  // Call it immediately
  debouncedFunc();
  expect(func).toHaveBeenCalledTimes(0); // func not called

  // Call it several times with 500ms between each call
  for(let i = 0; i < 10; i++) {
    clock.tick(500);
    debouncedFunc();
  }
  expect(func).toHaveBeenCalledTimes(0); // func not called

  // wait 1000ms
  clock.tick(1000);
  expect(func).toHaveBeenCalledTimes(1);  // func called
});
...