Created
May 23, 2023 12:32
-
-
Save ranpa/68ceb9b09382e5d0f93c957eb83aea9c to your computer and use it in GitHub Desktop.
Test scenarios for a declarative implementation of the setInterval method
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 { useInterval } from "./useInterval"; | |
describe("useInterval Hook", () => { | |
beforeAll(() => { | |
vi.useFakeTimers(); | |
}); | |
afterEach(() => { | |
vi.restoreAllMocks(); | |
vi.clearAllTimers(); | |
}); | |
afterAll(() => { | |
vi.useRealTimers(); | |
}); | |
describe("Scenario: start Interval", () => { | |
test(` | |
GIVEN an interval period in milliseconds | |
AND a callback function | |
WHEN this interval period has passed | |
THEN it should invoke the callback | |
`, () => { | |
const interval = 5000; | |
const callback = vi.fn(); | |
const { rerender } = renderHook(() => { | |
useInterval(callback, interval); | |
}); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(0); | |
vi.advanceTimersToNextTimer(); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(1); | |
vi.advanceTimersByTime(10 * interval); | |
rerender(); | |
expect(callback).toHaveBeenCalledTimes(11); | |
}); | |
}); | |
describe("Scenario: stop Interval", () => { | |
test(` | |
GIVEN an already started process | |
WHEN a undefined interval is passed | |
THEN it should stop (clear the timer) | |
`, () => { | |
const initialInterval = 1000; | |
const callback = vi.fn(); | |
const { rerender } = renderHook( | |
({ interval }) => { | |
useInterval(callback, interval); | |
}, | |
{ initialProps: { interval: initialInterval } }, | |
); | |
expect(callback).toHaveBeenCalledTimes(0); | |
vi.advanceTimersToNextTimer(); | |
rerender({ interval: initialInterval }); | |
expect(callback).toHaveBeenCalledTimes(1); | |
// @ts-expect-error Although the params from useInterval accept `undefined`, `rerender` doesn't get it | |
rerender({ interval: undefined }); | |
vi.advanceTimersByTime(10 * initialInterval); | |
// @ts-expect-error Although the params from useInterval accept `undefined`, `rerender` doesn't get it | |
rerender({ interval: undefined }); | |
expect(callback).toHaveBeenCalledTimes(1); | |
}); | |
}); | |
describe("Scenario: stop Interval before unmount", () => { | |
test(` | |
GIVEN an already started process | |
WHEN the component which renders the hook is unmounted | |
THEN it should stop (clear the timer) | |
`, () => { | |
const interval = 1000; | |
const callback = vi.fn(); | |
const { rerender, unmount } = renderHook(() => { | |
useInterval(callback, interval); | |
}); | |
vi.advanceTimersToNextTimer(); | |
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