如何创建单元测试用例以使用 jest 为我的去抖动和节流功能获得最大的代码覆盖率?
How do I create a unit test case to get maximum code coverage for my debounce and throttle function using jest?
我需要为库编写单元测试以获得最大的代码覆盖率——行覆盖率和分支覆盖率。
export const throttle = (fn, delay) => {
let last = 0;
return (...args) => {
const now = new Date().getTime();
if(now - last < delay) {
return;
}
last = now;
return fn(...args);
}
}
export const debounce = ( fn, delay) => {
let timeoutID;
return function(...args){
if (timeoutID){
clearTimeout(timeoutID);
}
timeoutID = setTimeout( () => {
fn(...args);
}, delay);
};
}
import { throttle} from './throttle'
import { debounce} from './debounce'
document.getElementById('myid').addEventListener( "click", debounce(e => {
console.log('clicked');
}, 2000))
document.getElementById('myid2').addEventListener('click', throttle(() => {
console.log('you clicked me');
}, 5000));
我有以下导出到主 js 页面的谴责和限制功能。我对如何为此使用 jest 编写测试用例感到困惑。我使用 lodash 阅读过的每个问题,但我只需要一个简单的单元测试用例来测试这两个函数。我是开玩笑的新手,在阅读文档后,我不明白谴责和节流中的“预期”是什么。
任何人都可以帮助我并提供一些说明吗?
单元测试不需要 DOM 相关的东西。要测试 throttle
,您应该模拟 Date
。为了测试 debounce
,你应该使用假计时器。 Date
和 setTimeout
有副作用,我们应该模拟它们以消除副作用。
throttle.js
:
export const throttle = (fn, delay) => {
let last = 0;
return (...args) => {
const now = new Date().getTime();
if (now - last < delay) {
return;
}
last = now;
return fn(...args);
};
};
throttle.test.js
:
import { throttle } from './throttle';
describe('65593662', () => {
describe('throttle', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should call function if now - last > delay', () => {
const fn = jest.fn();
const throttledFn = throttle(fn, 1000);
const getTimeSpy = jest.spyOn(Date.prototype, 'getTime').mockReturnValue(2000);
throttledFn('param');
expect(fn).toBeCalledWith('param');
expect(getTimeSpy).toBeCalledTimes(1);
});
it('should call function if now - last = delay', () => {
const fn = jest.fn();
const throttledFn = throttle(fn, 1000);
const getTimeSpy = jest.spyOn(Date.prototype, 'getTime').mockReturnValue(1000);
throttledFn('param');
expect(fn).toBeCalledWith('param');
expect(getTimeSpy).toBeCalledTimes(1);
});
it('should not call function if now - last < delay', () => {
const fn = jest.fn();
const throttledFn = throttle(fn, 1000);
const getTimeSpy = jest.spyOn(Date.prototype, 'getTime').mockReturnValue(100);
throttledFn('param');
expect(fn).not.toBeCalled();
expect(getTimeSpy).toBeCalledTimes(1);
});
});
});
debounce.js
:
export const debounce = (fn, delay) => {
let timeoutID;
return function (...args) {
if (timeoutID) {
clearTimeout(timeoutID);
}
timeoutID = setTimeout(() => {
fn(...args);
}, delay);
};
};
debounce.test.js
:
import { debounce } from './debounce';
jest.useFakeTimers();
describe('65593662', () => {
describe('debounce', () => {
it('should call function if timeoutID is undefined', () => {
const fn = jest.fn();
const debouncedFn = debounce(fn, 1000);
debouncedFn('param');
jest.advanceTimersByTime(1000);
expect(fn).toBeCalledWith('param');
expect(fn).toBeCalledTimes(1);
});
it('should not call function once if timeoutID exists', () => {
const fn = jest.fn();
const debouncedFn = debounce(fn, 1000);
debouncedFn('param');
debouncedFn('param');
debouncedFn('param');
jest.runAllTimers();
expect(fn).toBeCalledWith('param');
expect(fn).toBeCalledTimes(1);
});
});
});
单元测试结果:
PASS examples/65593662/throttle.test.ts
65593662
throttle
✓ should call function if now - last > delay (3 ms)
✓ should call function if now - last = delay
✓ should not call function if now - last < delay (1 ms)
PASS examples/65593662/debounce.test.ts
65593662
debounce
✓ should call function if timeoutID is undefined (5 ms)
✓ should not call function once if timeoutID exists (1 ms)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
debounce.ts | 100 | 100 | 100 | 100 |
throttle.ts | 100 | 100 | 100 | 100 |
-------------|---------|----------|---------|---------|-------------------
Test Suites: 2 passed, 2 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 4.168 s
我需要为库编写单元测试以获得最大的代码覆盖率——行覆盖率和分支覆盖率。
export const throttle = (fn, delay) => {
let last = 0;
return (...args) => {
const now = new Date().getTime();
if(now - last < delay) {
return;
}
last = now;
return fn(...args);
}
}
export const debounce = ( fn, delay) => {
let timeoutID;
return function(...args){
if (timeoutID){
clearTimeout(timeoutID);
}
timeoutID = setTimeout( () => {
fn(...args);
}, delay);
};
}
import { throttle} from './throttle'
import { debounce} from './debounce'
document.getElementById('myid').addEventListener( "click", debounce(e => {
console.log('clicked');
}, 2000))
document.getElementById('myid2').addEventListener('click', throttle(() => {
console.log('you clicked me');
}, 5000));
我有以下导出到主 js 页面的谴责和限制功能。我对如何为此使用 jest 编写测试用例感到困惑。我使用 lodash 阅读过的每个问题,但我只需要一个简单的单元测试用例来测试这两个函数。我是开玩笑的新手,在阅读文档后,我不明白谴责和节流中的“预期”是什么。 任何人都可以帮助我并提供一些说明吗?
单元测试不需要 DOM 相关的东西。要测试 throttle
,您应该模拟 Date
。为了测试 debounce
,你应该使用假计时器。 Date
和 setTimeout
有副作用,我们应该模拟它们以消除副作用。
throttle.js
:
export const throttle = (fn, delay) => {
let last = 0;
return (...args) => {
const now = new Date().getTime();
if (now - last < delay) {
return;
}
last = now;
return fn(...args);
};
};
throttle.test.js
:
import { throttle } from './throttle';
describe('65593662', () => {
describe('throttle', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should call function if now - last > delay', () => {
const fn = jest.fn();
const throttledFn = throttle(fn, 1000);
const getTimeSpy = jest.spyOn(Date.prototype, 'getTime').mockReturnValue(2000);
throttledFn('param');
expect(fn).toBeCalledWith('param');
expect(getTimeSpy).toBeCalledTimes(1);
});
it('should call function if now - last = delay', () => {
const fn = jest.fn();
const throttledFn = throttle(fn, 1000);
const getTimeSpy = jest.spyOn(Date.prototype, 'getTime').mockReturnValue(1000);
throttledFn('param');
expect(fn).toBeCalledWith('param');
expect(getTimeSpy).toBeCalledTimes(1);
});
it('should not call function if now - last < delay', () => {
const fn = jest.fn();
const throttledFn = throttle(fn, 1000);
const getTimeSpy = jest.spyOn(Date.prototype, 'getTime').mockReturnValue(100);
throttledFn('param');
expect(fn).not.toBeCalled();
expect(getTimeSpy).toBeCalledTimes(1);
});
});
});
debounce.js
:
export const debounce = (fn, delay) => {
let timeoutID;
return function (...args) {
if (timeoutID) {
clearTimeout(timeoutID);
}
timeoutID = setTimeout(() => {
fn(...args);
}, delay);
};
};
debounce.test.js
:
import { debounce } from './debounce';
jest.useFakeTimers();
describe('65593662', () => {
describe('debounce', () => {
it('should call function if timeoutID is undefined', () => {
const fn = jest.fn();
const debouncedFn = debounce(fn, 1000);
debouncedFn('param');
jest.advanceTimersByTime(1000);
expect(fn).toBeCalledWith('param');
expect(fn).toBeCalledTimes(1);
});
it('should not call function once if timeoutID exists', () => {
const fn = jest.fn();
const debouncedFn = debounce(fn, 1000);
debouncedFn('param');
debouncedFn('param');
debouncedFn('param');
jest.runAllTimers();
expect(fn).toBeCalledWith('param');
expect(fn).toBeCalledTimes(1);
});
});
});
单元测试结果:
PASS examples/65593662/throttle.test.ts
65593662
throttle
✓ should call function if now - last > delay (3 ms)
✓ should call function if now - last = delay
✓ should not call function if now - last < delay (1 ms)
PASS examples/65593662/debounce.test.ts
65593662
debounce
✓ should call function if timeoutID is undefined (5 ms)
✓ should not call function once if timeoutID exists (1 ms)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
debounce.ts | 100 | 100 | 100 | 100 |
throttle.ts | 100 | 100 | 100 | 100 |
-------------|---------|----------|---------|---------|-------------------
Test Suites: 2 passed, 2 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 4.168 s