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

React组件测试:如何用Vitest正确Mock jwt_decode函数解决报错?

修正后的AuthProvider单元测试代码

你的测试报错根源有两个:

  • vi.spyOn(jwt_decode)用法错误:spyOn要求第一个参数是对象,第二个是对象上的方法名,但jwt_decode是直接导入的独立函数,不是某个对象的属性,应该用vi.mock模拟整个模块。
  • 错误mock了useEffect:你试图监听AuthProvider的useEffect,这完全错误——useEffect是React内置钩子,不属于AuthProvider组件的属性。

另外原测试通过判断子元素是否存在验证状态的逻辑不成立,AuthProvider始终会渲染子组件,和isLoggedIn状态无关。正确做法是直接从Context中获取状态进行断言。

以下是修正后的完整测试代码:

import React, { useContext } from "react";
import { vi, expect, test, describe, beforeEach, afterEach } from 'vitest';
import jwt_decode from "jwt-decode";
import { render, screen } from "@testing-library/react";
import { AuthProvider, AuthContext } from "../contexts/authContext";

// 模拟jwt-decode模块
vi.mock("jwt-decode");

// 测试前后清理环境,避免测试污染
beforeEach(() => {
  localStorage.clear();
  // 重置document.cookie
  Object.defineProperty(document, 'cookie', {
    writable: true,
    value: '',
  });
  jwt_decode.mockReset();
});

afterEach(() => {
  vi.restoreAllMocks();
});

describe("AuthProvider", () => {
  test("renders children without errors", () => {
    render(
      <AuthProvider>
        <div>Test Child</div>
      </AuthProvider>
    );

    const childElement = screen.getByText("Test Child");
    expect(childElement).toBeInTheDocument();
  });

  test('sets isLoggedIn to false if cookie decoding fails', () => {
    // 让jwt_decode抛出错误
    jwt_decode.mockImplementation(() => {
      throw new Error("Decoding error");
    });

    // 创建组件消费AuthContext,用于获取状态
    const TestConsumer = () => {
      const { isLoggedIn } = useContext(AuthContext);
      return <div data-testid="is-logged-in">{isLoggedIn.toString()}</div>;
    };

    render(
      <AuthProvider>
        <TestConsumer />
      </AuthProvider>
    );
  
    // 断言isLoggedIn被设为false
    expect(screen.getByTestId("is-logged-in")).toHaveTextContent("false");
    // 断言localStorage同步更新状态
    expect(localStorage.getItem("isLoggedIn")).toBe("false");
  });
});

关键修正点说明:

  • 用vi.mock("jwt-decode")模拟整个模块,可在测试中灵活控制其行为。
  • 添加beforeEach/afterEach钩子,清理localStorage、document.cookie并重置mock,保证测试独立性。
  • 通过自定义测试组件消费Context,直接获取并展示isLoggedIn状态,实现精准断言。
  • 移除错误的useEffect mock代码,组件内部的钩子会自动执行,无需手动干预。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:37:28