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

如何在Jest中测试函数是否触发及window.fruit属性赋值?

解决Jest测试类方法调用及window属性赋值的问题

别发愁,我来帮你搞定这个Jest测试的问题!先模拟一个符合你描述的类结构(方便后续讲解):

class FruitHandler {
  constructor() {
    // 构造函数启动并调用setup
    this.setup();
  }

  setup() {
    // setup内部调用myFunction
    this.myFunction();
  }

  myFunction() {
    // 给window.fruit赋值
    window.fruit = 'Apple';
  }
}

你之前测试失败的原因大概率是mock时机不对或者没有正确处理window对象的测试隔离,下面给你分场景讲解解决方案:

场景1:myFunction是类的实例方法(最常见情况)

这种情况我们可以用jest.spyOn来监听方法调用,同时确保window对象在测试间被重置,避免污染。

测试代码如下:

describe('FruitHandler', () => {
  // 每个测试前重置window.fruit,防止测试间互相影响
  beforeEach(() => {
    delete window.fruit;
  });

  it('应该触发myFunction并将window.fruit设为Apple', () => {
    // 关键步骤:在实例化类之前,监听类原型上的myFunction方法
    const myFunctionSpy = jest.spyOn(FruitHandler.prototype, 'myFunction');

    // 实例化类,触发constructor → setup → myFunction的调用链
    new FruitHandler();

    // 断言myFunction被调用了一次
    expect(myFunctionSpy).toHaveBeenCalledTimes(1);
    // 断言window.fruit的赋值结果正确
    expect(window.fruit).toBe('Apple');

    // 清理spy,避免影响其他测试用例
    myFunctionSpy.mockRestore();
  });
});

为什么之前的mock没成功?

  • 如果你之前直接用jest.mock替换整个类,可能因为实例化时机早于mock,导致监听失效;
  • 如果替换了myFunction的实现但没保留原始逻辑,会导致window.fruit没有被赋值,自然打印window看不到这个属性;
  • 忘记重置window对象,之前测试的残留值会干扰当前测试。

场景2:myFunction是setup的内部私有函数

如果你的myFunction是setup里的私有内部函数(比如下面这种结构):

class FruitHandler {
  constructor() {
    this.setup();
  }

  setup() {
    // 内部私有函数,无法直接spy
    function myFunction() {
      window.fruit = 'Apple';
    }
    myFunction();
  }
}

这种情况下没法直接监听myFunction的调用,建议重构代码把myFunction提取为类的实例方法(方便测试);如果暂时不能重构,就直接断言副作用(window.fruit的值):

describe('FruitHandler', () => {
  beforeEach(() => {
    delete window.fruit;
  });

  it('应该将window.fruit设为Apple', () => {
    new FruitHandler();
    expect(window.fruit).toBe('Apple');
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:20:42