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

如何在Vitest中对登录成功后的Cookie创建进行单元测试?

修复Vitest单元测试的问题

原测试代码的核心问题

  • 重复mock模块:多次调用vi.mock("./auth.js")会覆盖之前的mock,导致只有最后一个mock生效,useCookie、useAPIFetch等mock无法正确工作。
  • 未初始化Pinia:测试Pinia store必须先创建Pinia实例并安装,否则store无法正常初始化。
  • 错误调用Store:直接使用导出的useAuthStore而不是通过Pinia实例获取的store对象,导致状态重置和方法调用异常。
  • Mock不完整:useCookie的mock没有正确模拟可赋值的value属性,且未处理state初始化和login方法中两次调用useCookie的场景。

修正后的测试代码

import { describe, test, expect, vi, beforeEach } from "vitest";
import { createPinia, setActivePinia } from "pinia";
import { useAuthStore } from "./auth";

// 正确mock Nuxt全局工具函数(这些不是auth.js导出的,是Nuxt提供的)
vi.mock("#app", () => ({
  useCookie: vi.fn(),
  useAPIFetch: vi.fn(),
  navigateTo: vi.fn(),
}));

import { useCookie, useAPIFetch, navigateTo } from "#app";

describe("useAuthStore", () => {
  let store;

  beforeEach(() => {
    // 初始化Pinia
    const pinia = createPinia();
    setActivePinia(pinia);
    // 创建store实例
    store = useAuthStore();

    // 清空所有mock调用记录
    useCookie.mockClear();
    useAPIFetch.mockClear();
    navigateTo.mockClear();

    // 模拟state初始化时的useCookie调用
    useCookie.mockReturnValue({ value: null });
  });

  test("login action should update session state and set cookie", async () => {
    const responseData = { token: "fakeToken" };
    // 模拟login里的useCookie调用,返回带有可写value的对象
    const mockCookie = { value: null };
    useCookie.mockReturnValueOnce(mockCookie);

    // 模拟API请求成功
    useAPIFetch.mockResolvedValue({
      data: { value: responseData },
    });

    await store.login({ username: "user", password: "pass" });

    // 验证session状态更新
    expect(store.session).toEqual(responseData);
    // 验证cookie的value被赋值
    expect(mockCookie.value).toEqual(responseData);
    // 验证useCookie的调用参数
    expect(useCookie).toHaveBeenNthCalledWith(1, "session"); // state初始化时的调用
    expect(useCookie).toHaveBeenNthCalledWith(2, "session", {
      maxAge: 86400,
      sameSite: true,
    }); // login里的调用
    // 验证API请求参数
    expect(useAPIFetch).toHaveBeenCalledWith("/login", {
      method: "POST",
      body: { username: "user", password: "pass" },
    });
  });

  test("logout action should reset session state and navigate to login", () => {
    // 设置初始session状态
    store.session = { token: "fakeToken" };
    // 模拟logout里的useCookie调用
    const mockCookie = { value: { token: "fakeToken" } };
    useCookie.mockReturnValue(mockCookie);

    store.logout();

    // 验证session状态重置
    expect(store.session).toBeNull();
    // 验证cookie的value被置空
    expect(mockCookie.value).toBeNull();
    // 验证导航调用
    expect(navigateTo).toHaveBeenCalledWith("/login");
  });
});

关键修正说明

  1. 正确Mock全局依赖:useCookie、useAPIFetch、navigateTo是Nuxt的全局工具,需要mock#app模块而不是./auth.js。
  2. Pinia初始化:每次测试前创建新的Pinia实例并设置为活跃状态,保证测试隔离。
  3. Store实例管理:通过useAuthStore()获取store实例,而不是直接使用导出的函数,确保状态正确绑定。
  4. Mock多场景调用:区分state初始化和login/logout中useCookie的不同调用,模拟可写的value属性以验证赋值逻辑。
  5. 精准验证调用顺序:使用toHaveBeenNthCalledWith验证useCookie的两次调用参数,确保逻辑符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:45:35