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

使用Jest 26.6.3时,setInterval内的Spy断言失效问题排查

问题分析与解决

这不是Jest的Bug,是你的操作存在两处问题:

核心原因

  1. Spy目标错误:你用jest.mock("./MyClass")自动mock了整个类,此时MyClass的所有实例方法都是指向原型上的mock函数。你在实例myObject上调用jest.spyOn,无法正确捕获原型方法的调用(实例的foo方法只是原型方法的引用,spy替换没有覆盖到真实调用路径)。
  2. 不必要的异步标记:测试中jest.advanceTimersByTime是同步操作,不需要添加async和done,这虽然不直接导致断言失败,但属于冗余代码。

修正后的测试代码

方法一:Spy类的原型方法

import { MyClass } from "./MyClass";

jest.mock("./MyClass");
jest.useFakeTimers();

describe("MyClass", () => {
  let myObject: MyClass = new MyClass();

  beforeEach(() => {
    jest.resetAllMocks();
  });

  it("works", () => {
    const fooSpy = jest.spyOn(myObject, "foo");

    myObject.foo();
    expect(fooSpy).toHaveBeenCalledTimes(1);
  });

  it("should work now", () => {
    // 改为监听类的原型方法,确保捕获所有实例调用
    const fooSpy = jest.spyOn(MyClass.prototype, "foo");
    const callback = () => {
      myObject.foo();
    };

    const intervalId = setInterval(callback, 1000);
    jest.advanceTimersByTime(1000);
    // 清理定时器,避免影响后续测试
    clearInterval(intervalId);

    expect(fooSpy).toHaveBeenCalledTimes(1);
  });
});

方法二:直接使用原型的Mock函数断言(更简洁)

因为已经通过jest.mock自动mock了类,原型上的foo本身就是Mock函数,可以直接用它来断言,无需额外Spy:

import { MyClass } from "./MyClass";

jest.mock("./MyClass");
jest.useFakeTimers();

describe("MyClass", () => {
  let myObject: MyClass = new MyClass();

  beforeEach(() => {
    jest.resetAllMocks();
  });

  it("works", () => {
    const fooSpy = jest.spyOn(myObject, "foo");

    myObject.foo();
    expect(fooSpy).toHaveBeenCalledTimes(1);
  });

  it("should work now", () => {
    const callback = () => {
      myObject.foo();
    };

    const intervalId = setInterval(callback, 1000);
    jest.advanceTimersByTime(1000);
    clearInterval(intervalId);

    // 直接断言原型上的mock方法调用次数
    expect(MyClass.prototype.foo).toHaveBeenCalledTimes(1);
  });
});

额外建议

使用fake timers后,记得在测试结束清理定时器(如clearInterval或jest.clearAllTimers()),避免定时器残留影响其他测试用例的执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:57:17