Skip to content

Commit

Permalink
Fix flakey test
Browse files Browse the repository at this point in the history
  • Loading branch information
longzheng committed Nov 17, 2024
1 parent fcf9ad1 commit 4391e4a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
22 changes: 16 additions & 6 deletions src/helpers/withRetry.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, it, expect, vi, afterEach } from 'vitest';
import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
import { withRetry } from './withRetry.js';
import { pinoLogger } from './logger.js';

Expand All @@ -9,8 +9,14 @@ vi.mock('./logger', () => ({
}));

describe('withRetry', () => {
beforeEach(() => {
vi.useFakeTimers();
});

afterEach(() => {
vi.clearAllMocks();

vi.useRealTimers();
});

it('should return result on first attempt', async () => {
Expand Down Expand Up @@ -60,19 +66,23 @@ describe('withRetry', () => {
.mockResolvedValueOnce('success');

const delayMilliseconds = 100;
const start = Date.now();

const result = await withRetry(fn, {
let result;
void withRetry(fn, {
attempts: 3,
functionName: 'testFn',
delayMilliseconds,
});
}).then((res) => (result = res));

const end = Date.now();
// before retry
await vi.advanceTimersByTimeAsync(delayMilliseconds - 1);
expect(result).toBeUndefined();
expect(fn).toHaveBeenCalledTimes(1);

// after retry
await vi.advanceTimersByTimeAsync(delayMilliseconds);
expect(result).toBe('success');
expect(fn).toHaveBeenCalledTimes(2);
expect(end - start).toBeGreaterThanOrEqual(delayMilliseconds);
expect(pinoLogger.warn).toHaveBeenCalledTimes(1);
});
});
6 changes: 4 additions & 2 deletions src/helpers/withRetry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { setTimeout } from 'node:timers/promises';
import { pinoLogger } from './logger.js';

export async function withRetry<T>(
Expand All @@ -25,7 +24,10 @@ export async function withRetry<T>(
);

if (attempt < attempts && delayMilliseconds) {
await setTimeout(delayMilliseconds);
// todo: refactor to use import { setTimeout } from 'node:timers/promises'; when vitest supports mocking it
await new Promise((resolve) =>
setTimeout(resolve, delayMilliseconds),
);
} else if (attempt === attempts) {
// If this was the last attempt, rethrow the error
throw error;
Expand Down

0 comments on commit 4391e4a

Please sign in to comment.