Joj*_*oji 5 javascript unit-testing typescript jestjs
我有一个我想测试的重试 util 函数。看起来像这样
export const sleep = (t: number) => new Promise((r) => setTimeout(r, t));
type RetryFn = (
fn: Function,
config: {
retryIntervel: number;
retryTimeout: number;
predicate: Function;
onRetrySuccess?: Function;
onRetryFail?: Function;
}
) => Promise<any>;
export const retry: RetryFn = async (
fn,
{ predicate, onRetrySuccess, onRetryFail, retryIntervel, retryTimeout }
) => {
const startTime = Date.now();
let retryCount = 0;
while (Date.now() - startTime < retryTimeout) {
try {
const ret = await fn();
if (predicate(ret)) {
if (retryCount > 0) onRetrySuccess && onRetrySuccess();
return ret;
} else {
throw new Error();
}
} catch {
retryCount++;
}
await sleep(retryIntervel);
}
if (onRetryFail) onRetryFail();
};
Run Code Online (Sandbox Code Playgroud)
它的作用是在给定的时间间隔内重试该函数一段时间。
我想我可以使用jest.advanceTimersByTime
提前计时器来测试重试发生的次数。
export const sleep = (t: number) => new Promise((r) => setTimeout(r, t));
type RetryFn = (
fn: Function,
config: {
retryIntervel: number;
retryTimeout: number;
predicate: Function;
onRetrySuccess?: Function;
onRetryFail?: Function;
}
) => Promise<any>;
export const retry: RetryFn = async (
fn,
{ predicate, onRetrySuccess, onRetryFail, retryIntervel, retryTimeout }
) => {
const startTime = Date.now();
let retryCount = 0;
while (Date.now() - startTime < retryTimeout) {
try {
const ret = await fn();
if (predicate(ret)) {
if (retryCount > 0) onRetrySuccess && onRetrySuccess();
return ret;
} else {
throw new Error();
}
} catch {
retryCount++;
}
await sleep(retryIntervel);
}
if (onRetryFail) onRetryFail();
};
Run Code Online (Sandbox Code Playgroud)
但似乎无论我将计时器提前多少,该函数都只会被调用一次。
您可以在codesandbox上找到代码:https://codesandbox.io/s/lucid-knuth-e810e ?file=/src/index.test.ts
但是, codesandbox有一个已知问题TypeError: jest.advanceTimersByTime is not a function
,它会不断抛出此错误。该错误不会在本地出现。
正是因为这个。
这是我在测试助手文件中使用的内容:
const tick = () => new Promise(res => setImmediate(res));
export const advanceTimersByTime = async time => jest.advanceTimersByTime(time) && (await tick());
export const runOnlyPendingTimers = async () => jest.runOnlyPendingTimers() && (await tick());
export const runAllTimers = async () => jest.runAllTimers() && (await tick());
Run Code Online (Sandbox Code Playgroud)
在我的测试文件中,我导入了我的助手,而不是调用jest.advanceTimersByTime
,而是调用await
了我的advanceTimersByTime
函数。
在您的具体示例中,您只需要在await
调用后调用一个函数advanceTimersByTime
- 像这样:
// top of your test file
const tick = () => new Promise(res => setImmediate(res));
... the rest of your existing test file
jest.advanceTimersByTime(1000);
expect(fn).toHaveBeenCalledTimes(1);
expect(onRetrySuccessFn).not.toHaveBeenCalled();
jest.advanceTimersByTime(1000);
await tick(); // this line
expect(fn).toHaveBeenCalledTimes(2);
expect(onRetrySuccessFn).not.toHaveBeenCalled();
jest.advanceTimersByTime(2000);
await tick(); // this line
expect(fn).toHaveBeenCalledTimes(3)
expect(onRetrySuccessFn).toHaveBeenCalledTimes(1);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15324 次 |
最近记录: |