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

Jest重置Mock无效:多测试文件共享执行状态污染问题

Jest多测试文件Mock污染问题解决

问题场景

为依赖near-api-js、Ethersjs等外部库的工具类编写单元测试时,通过index文件统一导入执行所有测试用例,但运行发现前一测试文件的Mock未被清理,导致后续测试调用的是库的原始版本而非Mock版本。尝试过jest.clearAllMocks()、jest.resetAllMocks()以及afterEach/afterAll清理逻辑,均未解决问题。

核心原因与解决办法

1. 避免嵌套调用测试集,改用直接导入

当前index文件通过describe嵌套调用其他测试函数(如utilActivity()),会导致测试上下文共享,Mock无法隔离。正确做法是直接在index文件中导入测试文件,让Jest为每个文件创建独立上下文:

// index.test.js
import './utilActivity.test.js';
import './utilNotifications.test.js';
import './utilNear.test.js';

2. 使用jest.restoreAllMocks()恢复原始实现

jest.clearAllMocks()仅清除调用记录,jest.resetAllMocks()重置Mock初始状态,但都不会恢复被jest.spyOn替换的原始方法。需在每个测试文件的顶层describe中添加:

afterEach(() => {
  jest.restoreAllMocks(); // 恢复所有被spyOn替换的原始方法
  jest.clearAllMocks(); // 清除Mock调用记录
});

3. 重置模块缓存,避免Mock污染

对于jest.mock定义的模块Mock,若模块被缓存可能导致污染。可在测试文件顶部添加:

beforeEach(() => {
  jest.resetModules(); // 重置模块缓存,确保每次测试重新导入模块
});

4. 重置全局状态

针对StaticStore这类全局状态,需在每个测试前重置到初始状态:

beforeEach(() => {
  StaticStore.dispatch(resetAppState()); // 替换为实际的状态重置逻辑
});

修正后的测试文件示例

utilNear.test.js

jest.mock("near-api-js", () => {
  const originalModule = jest.requireActual("near-api-js");
  return {
    __esModule: true,
    ...originalModule,
    KeyPair: {
      fromString: jest.fn().mockReturnValue("5eeb5878647747efa8d53129c85f0cfc60370049e40fc9dc2f331d51db2f58d1"),
    },
    providers: {
      JsonRpcProvider: jest.fn().mockReturnValue({
        query: jest.fn().mockReturnValue("access ket"),
        block: jest.fn().mockReturnValue({
          header: { hash: "0x11111111111111" },
        }),
      }),
    },
    transactions: {
      createTransaction: jest.fn().mockImplementation(() => "neartx"),
      signTransaction: jest.fn().mockReturnValue(["", "5eeb5878647747efa8d53129c85f0cfc60370049e40fc9dc2f331d51db2f58d1"]),
      functionCall: jest.fn(),
    },
    utils: {
      PublicKey: { from: jest.fn() },
      serialize: { base_decode: jest.fn() },
    },
  };
});

describe("utils.near", () => {
  beforeEach(() => {
    jest.restoreAllMocks();
    jest.clearAllMocks();
    StaticStore.dispatch(resetAppState()); // 重置全局状态
    jest.spyOn(CachedService, "getHashedPassword").mockReturnValue("0x4cc447191e19f3d492b3e6dc74172a6ea597c68880b62674e21af15b90022e35");
  });

  describe("validateAccessKey", () => {
    it("should return accessKey if permission is 'FullAccess'", () => {
      expect(utilNear.validateAccessKey(transaction, accessKey)).toBe(accessKey);
    });
    it("should return null if transaction receiver_id differs from accessKey's receiver_id", () => {
      expect(utilNear.validateAccessKey(transaction, accessKey2)).toBeNull();
    });
    it("should return false if transaction action type is not FunctionCall", () => {
      expect(utilNear.validateAccessKey(transaction3, accessKey3)).toBeFalsy();
    });
    it("should return false if transaction methodName is included in accessKey's method_names", () => {
      expect(utilNear.validateAccessKey(transaction4, accessKey4)).toBeFalsy();
    });
    it("should return truthy if transaction methodName is not included in accessKey's method_names", () => {
      expect(utilNear.validateAccessKey(transaction5, accessKey5)).toBeTruthy();
    });
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 08:47:46