我正在尝试为防抖功能编写单元测试。我很难考虑这一点。
这是代码:
chrome.devtools.inspectedWindow.eval('inspect(document.body)');
我应该如何开始?
答案 0 :(得分:7)
您可能需要检查去抖功能中的逻辑:
timeout
始终由最后一个if()
语句设置this
将始终为undefined
,因为arrow functions use "the this
value of the enclosing lexical context"和debouncer()
被设计为独立功能。话虽如此,听起来您真正的问题是关于测试去抖动功能。
您可以使用模拟程序来跟踪函数调用并使用伪造的计时器来模拟时间的流逝,从而测试功能是否被去抖动。
下面是一个简单的示例,其中使用了Jest
Mock Function和Sinon
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);
});
});
答案 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);
});