3ccd1262f9
基于 Vitest 搭建测试基础设施,覆盖后端纯函数、API 路由、 前端 hooks、UI 组件和页面级集成测试。
101 lines
2.5 KiB
TypeScript
101 lines
2.5 KiB
TypeScript
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);
|
|
});
|
|
});
|