如何在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
相关产品推荐
相关产品推荐

