javascript 去抖动功能的 Jest 单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52224447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jest unit test for a debounce function
提问by RecipeCreator
I am trying to write a unit test for debounce function. I'm having a hard time thinking about it.
我正在尝试为 debounce 函数编写单元测试。我很难去想。
This is the code:
这是代码:
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);
};
}
How should I start?
我应该如何开始?
回答by Brian Adams
You will probably want to check the logic in your debouncer function:
您可能需要检查 debouncer 函数中的逻辑:
timeoutwill always be set by that lastif()statementthiswill always beundefinedsince arrow functions use "thethisvalue of the enclosing lexical context"anddebouncer()is designed to be used as a stand-alone function.
timeout将始终由最后一条if()语句设置this将始终是,undefined因为箭头函数使用“this封闭词法上下文的值”并且debouncer()被设计为用作独立函数。
Having said that, it sounds like your real question is about testing debounced functions.
话虽如此,听起来您真正的问题是关于测试去抖动函数。
Testing debounced functions
测试去抖动函数
You can test that a function is debounced by using a mock to track function calls and fake timers to simulate the passage of time.
您可以通过使用模拟来跟踪函数调用和使用假计时器来模拟时间的流逝来测试函数是否已去抖动。
Here is a simple example using a JestMock Functionand Sinonfake timersof a function debounced using debounce()from Lodash:
这是一个使用Jest模拟函数和使用from去抖动的函数的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
});
回答by tswistak
Actually, you don't need to use Sinon to test debounces. Jest can mock all timers in JS code.
实际上,您不需要使用Sinon 来测试去抖动。Jest 可以模拟 JS 代码中的所有计时器。
Check out following code (it's TypeScript, but you can easily translate it to 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);
});
});
More information: https://jestjs.io/docs/en/timer-mocks.html
回答by Mis94
If in your code you are doing so:
如果在您的代码中您这样做:
import debounce from 'lodash/debounce';
myFunc = debounce(myFunc, 300);
and you want to test the function myFuncor a function calling it, then in your test you can mock the implementation of debounceusing jestto make it just return your function:
并且您想测试该函数myFunc或调用它的函数,然后在您的测试中,您可以模拟debounceusing的实现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
// ...
});
Source: https://gist.github.com/apieceofbart/d28690d52c46848c39d904ce8968bb27
来源:https: //gist.github.com/apieceofbart/d28690d52c46848c39d904ce8968bb27

