You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Cypress模拟OAuth登录会话后个人页显示无资料问题排查

问题分析

首页能正常显示登录状态,是因为你通过cy.intercept拦截了/api/auth/session接口,返回了模拟的会话数据,前端useSession能正确拿到登录信息。但个人资料页的userInfo是通过服务器端的getServerSideProps直接调用getUserInfo操作数据库获取的——测试时这个查询会访问真实数据库,而数据库中没有test0000这个slug的用户,因此返回null,导致页面显示“No profile”。

解决方案

以下是三种可行的解决思路,按场景适配选择:


方案1:测试环境下Mock数据库查询函数

直接修改getUserInfo的实现,在测试环境跳过真实数据库查询,返回模拟数据:

// @scripts/prisma/getUserInfo.ts
import { User } from "@prisma/client";

export async function getUserInfo(slug: string): Promise<User | null> {
  // 测试环境直接返回模拟数据
  if (process.env.NODE_ENV === "test") {
    return {
      bio: "Lorem Testum",
      name: "test",
      email: "test@test.com",
      slug: "test0000",
      id: "strasnedlouhejstring",
      isActive: true,
      // 补充User类型要求的其他必填字段(如createdAt、updatedAt)
      createdAt: new Date(),
      updatedAt: new Date()
    };
  }

  // 生产/开发环境的真实数据库查询逻辑(保留原代码)
  // ...
}

然后在Cypress配置中设置测试环境变量:

// cypress.config.js
module.exports = defineConfig({
  env: {
    NODE_ENV: "test"
  },
  // 其他Cypress配置
});

方案2:将数据库查询改为API调用并拦截

把服务器端直接调用数据库的逻辑改成调用内部API,再用Cypress拦截该API返回模拟数据:

步骤1:创建用户信息API路由

新建pages/api/user/[slug].ts:

import { getUserInfo } from "@scripts/prisma/getUserInfo";
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { slug } = req.query;
  if (typeof slug !== "string") {
    return res.status(400).json({ error: "Invalid slug" });
  }
  const user = await getUserInfo(slug);
  res.status(200).json(user);
}

步骤2:修改getServerSideProps调用API

export const getServerSideProps: GetServerSideProps = async (context) => {
  const slug = context.query.userProfile?.toString();

  if (slug) {
    // 替换原数据库查询为API调用
    const res = await fetch(`http://localhost:3000/api/user/${slug}`);
    const user = await res.json();

    if (user) {
      return {
        props: { userInfo: user },
      };
    }
  }

  return {
    props: { userInfo: null },
  };
};

步骤3:更新Cypress命令与测试

在login命令中添加API拦截:

Cypress.Commands.add("login", () => {
  cy.intercept("/api/auth/session", { fixture: "session.json" }).as("session");
  // 拦截用户信息API,返回模拟数据
  cy.intercept("/api/user/test0000", { fixture: "userInfo.json" }).as("userInfo");
  cy.setCookie("next-auth.session-token", "testcookie");
  Cypress.Cookies.preserveOnce("next-auth.session-token");
});

创建cypress/fixtures/userInfo.json:

{
  "bio": "Lorem Testum",
  "name": "test",
  "email": "test@test.com",
  "slug": "test0000",
  "id": "strasnedlouhejstring",
  "isActive": true,
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-01T00:00:00.000Z"
}

修改测试代码验证个人资料页:

describe("Cypress login", () => {
  it("should display user profile correctly", () => {
    cy.login();
    cy.visit("/userProfile/test0000"); // 替换为你的个人资料页实际路径
    cy.wait(["@session", "@userInfo"]);
    cy.get("h1").should("not.contain", "No profile");
    cy.get(".profile-bio").should("contain", "Lorem Testum"); // 替换为页面实际元素选择器
  });
});

方案3:组件测试直接传递Props

如果仅需验证组件渲染逻辑,可使用Cypress组件测试,直接给UserProfile组件传递userInfo:

import UserProfile from "../../pages/userProfile/[userProfile]";

describe("UserProfile Component", () => {
  it("renders profile content when userInfo exists", () => {
    cy.mount(<UserProfile userInfo={{
      bio: "Lorem Testum",
      name: "test",
      email: "test@test.com",
      slug: "test0000",
      id: "strasnedlouhejstring",
      isActive: true,
      createdAt: new Date(),
      updatedAt: new Date()
    }} />);
    cy.get("h1").should("not.contain", "No profile");
  });
});

内容的提问来源于stack exchange,提问作者MRZTyy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 12:55:20