Skip to content

Instantly share code, notes, and snippets.

@ranpa
Created May 23, 2023 12:31
Show Gist options
  • Save ranpa/7fbf942ab4f2f70e3a7b7e63480dda0a to your computer and use it in GitHub Desktop.
Save ranpa/7fbf942ab4f2f70e3a7b7e63480dda0a to your computer and use it in GitHub Desktop.
Test scenarios for a declarative implementation of the setTimeout method
import {
afterAll,
afterEach,
beforeAll,
describe,
expect,
test,
vi,
} from "vitest";
import { renderHook } from "@testing-library/react";
import { useTimeout } from "./useTimeout";
describe("useTimeout Hook", () => {
beforeAll(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.restoreAllMocks();
vi.clearAllTimers();
});
afterAll(() => {
vi.useRealTimers();
});
describe("Scenario: start timeout", () => {
test(`
GIVEN a delay period in milliseconds
AND a callback function
WHEN this delay period has passed
THEN it should invoke the callback
`, () => {
const delay = 5000;
const callback = vi.fn();
const { rerender } = renderHook(() => {
useTimeout(callback, delay);
});
rerender();
expect(callback).toHaveBeenCalledTimes(0);
vi.advanceTimersToNextTimer();
rerender();
expect(callback).toHaveBeenCalledTimes(1);
vi.advanceTimersByTime(10 * delay);
rerender();
expect(callback).toHaveBeenCalledTimes(1);
});
});
describe("Scenario: stop Timeout before unmount", () => {
test(`
GIVEN an already started process
WHEN the component which renders the hook is unmounted
AND the delay has not passed yet
THEN it shouldn't invoke the callback
`, () => {
const delay = 1000;
const callback = vi.fn();
const { rerender, unmount } = renderHook(() => {
useTimeout(callback, delay);
});
rerender();
expect(callback).toHaveBeenCalledTimes(0);
unmount();
vi.advanceTimersByTime(10 * delay);
expect(callback).toHaveBeenCalledTimes(0);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment