test: 添加完整测试套件(52 个文件,326 个用例)
基于 Vitest 搭建测试基础设施,覆盖后端纯函数、API 路由、 前端 hooks、UI 组件和页面级集成测试。
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { renderHook, waitFor, act } from "@testing-library/react";
|
||||
|
||||
let esInstances: { onmessage?: (e: MessageEvent) => void; onerror?: () => void; onopen?: () => void; close: ReturnType<typeof vi.fn> }[] = [];
|
||||
|
||||
class MockEventSource {
|
||||
onmessage: ((e: MessageEvent) => void) | null = null;
|
||||
onerror: (() => void) | null = null;
|
||||
onopen: (() => void) | null = null;
|
||||
close = vi.fn();
|
||||
|
||||
constructor(_url: string) {
|
||||
esInstances.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
vi.stubGlobal("EventSource", MockEventSource);
|
||||
|
||||
vi.mock("swr", () => ({
|
||||
default: vi.fn().mockReturnValue({
|
||||
data: {
|
||||
roomId: "ROOM01",
|
||||
userCount: 2,
|
||||
match: null,
|
||||
matchType: null,
|
||||
matchLikes: 0,
|
||||
runnerUps: [],
|
||||
likeCounts: {},
|
||||
swipeCounts: {},
|
||||
restaurants: [],
|
||||
creatorId: "user-1",
|
||||
locked: false,
|
||||
users: ["user-1", "user-2"],
|
||||
userProfiles: {},
|
||||
scene: "eat",
|
||||
},
|
||||
error: null,
|
||||
isLoading: false,
|
||||
mutate: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
import { useRoomPolling } from "./useRoomPolling";
|
||||
|
||||
beforeEach(() => {
|
||||
esInstances = [];
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("useRoomPolling", () => {
|
||||
it("returns room data from SWR", () => {
|
||||
const { result } = renderHook(() => useRoomPolling("ROOM01"));
|
||||
|
||||
expect(result.current.userCount).toBe(2);
|
||||
expect(result.current.users).toEqual(["user-1", "user-2"]);
|
||||
expect(result.current.scene).toBe("eat");
|
||||
});
|
||||
|
||||
it("creates EventSource connection", () => {
|
||||
renderHook(() => useRoomPolling("ROOM01"));
|
||||
expect(esInstances.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("returns defaults when no roomId", () => {
|
||||
const { result } = renderHook(() => useRoomPolling(undefined));
|
||||
expect(result.current.userCount).toBe(2);
|
||||
});
|
||||
|
||||
it("returns notFound from error state", async () => {
|
||||
const useSWR = vi.mocked((await import("swr")).default);
|
||||
useSWR.mockReturnValue({
|
||||
data: undefined,
|
||||
error: new Error("NOT_FOUND"),
|
||||
isLoading: false,
|
||||
mutate: vi.fn(),
|
||||
} as never);
|
||||
|
||||
const { result } = renderHook(() => useRoomPolling("ROOM01"));
|
||||
expect(result.current.notFound).toBe(true);
|
||||
});
|
||||
|
||||
it("cleans up EventSource on unmount", () => {
|
||||
const { unmount } = renderHook(() => useRoomPolling("ROOM01"));
|
||||
const es = esInstances[esInstances.length - 1];
|
||||
unmount();
|
||||
expect(es.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user