玩笑单元测试的反跳功能

时间:2018-09-07 14:18:11

标签: javascript unit-testing jestjs debounce

我正在尝试为防抖功能编写单元测试。我很难考虑这一点。

这是代码:

chrome.devtools.inspectedWindow.eval('inspect(document.body)');

我应该如何开始?

5 个答案:

答案 0 :(得分:7)

您可能需要检查去抖功能中的逻辑:

话虽如此,听起来您真正的问题是关于测试去抖动功能。

测试去抖动功能

您可以使用模拟程序来跟踪函数调用并使用伪造的计时器来模拟时间的流逝,从而测试功能是否被去抖动。

下面是一个简单的示例,其中使用了Jest Mock FunctionSinon fake timers的函数,这些函数使用debounce() from 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
});

答案 1 :(得分:2)

实际上,您不需要使用Sinon来测试去抖动。笑话可以模拟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

答案 2 :(得分:2)

如果在您的代码中您正在这样做:

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

答案 3 :(得分:2)

我喜欢这个类似的版本,更容易失败

    jest.useFakeTimers();
    test('execute just once', () => {
     const func = jest.fn();
     const debouncedFunc = debounce(func, 500);
     // execute for the first time
     debouncedFunc();
     // move on the timer
     jest.advanceTimersByTime(250);
     // try to execute a 2nd time
     debouncedFunc();
    
     // fast-forward time
     jest.runAllTimers();
    
     expect(func).toBeCalledTimes(1);
    });

答案 4 :(得分:0)

由于我正在使用摩卡咖啡,所以不确定这将如何与笑话一起工作,但对于在那里的任何人来说,这都是一个简单的解决方案:

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);
  });
相关问题