Kuma/tests/hooks/useIsMobile.test.ts
2026-04-27 20:28:43 +02:00

71 lines
2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { renderHook, act } from "@testing-library/react";
import { useIsMobile } from "@/src/hooks/use-mobile";
const mockAddEventListener = vi.fn();
const mockRemoveEventListener = vi.fn();
function setWindowWidth(width: number) {
Object.defineProperty(window, "innerWidth", {
writable: true,
configurable: true,
value: width,
});
Object.defineProperty(window, "matchMedia", {
writable: true,
configurable: true,
value: (query: string) => ({
matches: width < 768,
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: mockAddEventListener,
removeEventListener: mockRemoveEventListener,
dispatchEvent: vi.fn(),
}),
});
}
beforeEach(() => {
mockAddEventListener.mockClear();
mockRemoveEventListener.mockClear();
});
afterEach(() => {
vi.restoreAllMocks();
});
describe("useIsMobile", () => {
it("gibt true zurück bei schmaler Viewport-Breite (<768px)", () => {
setWindowWidth(500);
const { result } = renderHook(() => useIsMobile());
expect(result.current).toBe(true);
});
it("gibt false zurück bei breiter Viewport-Breite (>=768px)", () => {
setWindowWidth(1024);
const { result } = renderHook(() => useIsMobile());
expect(result.current).toBe(false);
});
it("gibt false zurück genau bei 768px", () => {
setWindowWidth(768);
const { result } = renderHook(() => useIsMobile());
expect(result.current).toBe(false);
});
it("registriert einen Event-Listener auf matchMedia", () => {
setWindowWidth(500);
renderHook(() => useIsMobile());
expect(mockAddEventListener).toHaveBeenCalledWith("change", expect.any(Function));
});
it("entfernt den Event-Listener beim Unmount", () => {
setWindowWidth(500);
const { unmount } = renderHook(() => useIsMobile());
unmount();
expect(mockRemoveEventListener).toHaveBeenCalledWith("change", expect.any(Function));
});
});