test: 添加完整测试套件(52 个文件,326 个用例)
基于 Vitest 搭建测试基础设施,覆盖后端纯函数、API 路由、 前端 hooks、UI 组件和页面级集成测试。
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
||||
import React from "react";
|
||||
import { ToastContext, type ToastContextValue } from "@/hooks/useToast";
|
||||
|
||||
vi.mock("next/navigation", () => ({
|
||||
useRouter: () => ({
|
||||
push: vi.fn(),
|
||||
back: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/userId", () => ({
|
||||
getUserId: vi.fn().mockReturnValue("user-1"),
|
||||
getCachedPreferences: vi.fn().mockReturnValue({}),
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/sceneConfig", () => ({
|
||||
SCENES: ["eat", "drinks"],
|
||||
getSceneConfig: vi.fn().mockReturnValue({
|
||||
key: "eat",
|
||||
label: "餐厅",
|
||||
emoji: "🍜",
|
||||
verb: "吃",
|
||||
poiTypes: "050000",
|
||||
defaultImage: "",
|
||||
hotTags: ["火锅", "日料", "烧烤"],
|
||||
priceOptions: [{ label: "不限", value: "any" }],
|
||||
tagLabel: "口味",
|
||||
tagPlaceholder: "想吃什么?",
|
||||
loadingText: "正在搜索...",
|
||||
emptyError: "没找到",
|
||||
subtitle: "一起选餐厅",
|
||||
inviteText: "邀请你",
|
||||
shareTitle: "分享",
|
||||
shareText: "一起来",
|
||||
qrSubtitle: "扫码加入",
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("@/hooks/useGeolocation", () => ({
|
||||
useGeolocation: vi.fn().mockReturnValue({
|
||||
status: "success",
|
||||
coords: { lat: 31.2, lng: 121.4 },
|
||||
locationName: "上海",
|
||||
retry: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/room", () => ({
|
||||
joinRoom: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
const mockFetch = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ suggestions: [] }),
|
||||
});
|
||||
vi.stubGlobal("fetch", mockFetch);
|
||||
|
||||
import PanicPage from "./page";
|
||||
|
||||
const toastCtx: ToastContextValue = { show: vi.fn() };
|
||||
|
||||
function renderPage() {
|
||||
return render(
|
||||
React.createElement(
|
||||
ToastContext.Provider,
|
||||
{ value: toastCtx },
|
||||
React.createElement(PanicPage),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("PanicPage", () => {
|
||||
it("renders page title", () => {
|
||||
renderPage();
|
||||
expect(screen.getByText("极速救场")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders location search input", () => {
|
||||
renderPage();
|
||||
expect(screen.getByPlaceholderText(/搜索位置/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders distance options", () => {
|
||||
renderPage();
|
||||
expect(screen.getByText("1km")).toBeInTheDocument();
|
||||
expect(screen.getByText("3km")).toBeInTheDocument();
|
||||
expect(screen.getByText("5km")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders scene selector with labels", () => {
|
||||
renderPage();
|
||||
expect(screen.getAllByText("餐厅").length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user