Created
May 23, 2023 13:08
-
-
Save ranpa/385411f3f289709413de59c4bf7edb16 to your computer and use it in GitHub Desktop.
Test scenarios for a declarative way of calling a callback from time to time (polling)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
afterAll, | |
afterEach, | |
beforeAll, | |
describe, | |
expect, | |
test, | |
vi, | |
} from "vitest"; | |
import { renderHook } from "@testing-library/react"; | |
import { usePolling } from "./usePolling"; | |
describe("usePolling Hook", () => { | |
beforeAll(() => { | |
vi.useFakeTimers(); | |
}); | |
afterEach(() => { | |
vi.resetAllMocks(); | |
}); | |
afterAll(() => { | |
vi.useRealTimers(); | |
vi.restoreAllMocks(); | |
}); | |
describe("Scenario: start polling", () => { | |
test(` | |
GIVEN an interval period in milliseconds | |
AND a callback function | |
WHEN the hook is rendered | |
THEN it should start polling (invoke the callback) | |
`, () => { | |
const interval = 5000; | |
const callback = vi.fn(); | |
const { rerender } = renderHook(() => usePolling({ callback, interval })); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(1); | |
vi.advanceTimersToNextTimer(); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(2); | |
vi.advanceTimersByTime(10 * interval); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(12); | |
}); | |
}); | |
describe("Scenario: start polling after a given delay", () => { | |
test(` | |
GIVEN an interval period (in milliseconds) | |
AND a delay period (in millisecond) | |
AND a callback function | |
WHEN the hook is renreded | |
THEN it should wait the delay period | |
AND start polling (invoke the callback) | |
`, () => { | |
const interval = 1000; | |
const delay = 20000; | |
const callback = vi.fn(); | |
const { rerender } = renderHook(() => | |
usePolling({ callback, interval, delay }), | |
); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(0); | |
vi.advanceTimersByTime(delay); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(1); | |
vi.advanceTimersByTime(interval / 2); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(1); | |
vi.advanceTimersByTime(10 * interval); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(11); | |
}); | |
}); | |
describe("Scenario: stop polling", () => { | |
test(` | |
GIVEN an already started polling process | |
WHEN a undefined interval is passed | |
THEN it should stop polling (clear the timer) | |
`, () => { | |
const initialInterval = 1000; | |
const callback = vi.fn(); | |
const { rerender } = renderHook( | |
({ interval }) => usePolling({ callback, interval }), | |
{ | |
initialProps: { interval: initialInterval }, | |
}, | |
); | |
rerender({ interval: initialInterval }); | |
expect(callback).toHaveBeenCalledTimes(1); | |
rerender({ interval: undefined }); | |
vi.advanceTimersByTime(10 * initialInterval); | |
rerender({ interval: undefined }); | |
expect(callback).toHaveBeenCalledTimes(1); | |
}); | |
}); | |
describe("Scenario: stop polling before unmount", () => { | |
test(` | |
GIVEN an already started polling process | |
WHEN the component which renders the hook is unomounted | |
THEN it should stop polling (clear the timer) | |
`, () => { | |
const interval = 1000; | |
const callback = vi.fn(); | |
const { rerender, unmount } = renderHook(() => | |
usePolling({ callback, interval }), | |
); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(1); | |
unmount(); | |
vi.advanceTimersByTime(10 * interval); | |
expect(callback).toHaveBeenCalledTimes(1); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment