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

Jest模拟函数:ES6类Store的方法调用与属性变化测试求助

用Jest测试ES6 Store类的实用指南

嘿,作为经常在Stack Overflow帮人搞定Jest测试问题的老鸟,我来给你梳理下怎么测试这个ES6 Store类~毕竟我也踩过不少这类测试的坑,给你分享点实用的方法:

一、测试方法是否被调用

不管是Store自身的方法,还是它继承的父类方法,Jest的spyOn和mock能力都能轻松搞定:

1. 测试自身方法的调用

假设你的Store类结构是这样的:

class BaseStore {
  update() {}
}

class Store extends BaseStore {
  constructor() {
    super();
    this.count = 0;
  }

  increment() {
    this.count++;
    this.update();
  }
}

要测试increment是否调用了update方法,你可以这么写:

test('调用increment时应该触发update方法', () => {
  // 实例化Store
  const store = new Store();
  // 用spyOn监听update方法
  const updateSpy = jest.spyOn(store, 'update');
  
  // 执行要测试的方法
  store.increment();
  
  // 断言方法被调用了1次
  expect(updateSpy).toHaveBeenCalledTimes(1);
  // 如果方法有参数,还能断言参数是否符合预期
  // expect(updateSpy).toHaveBeenCalledWith(expect.any(Number));
});

2. 测试父类方法的调用

如果要验证Store的方法是否调用了父类的方法,可以直接监听父类的原型方法:

test('increment应该调用父类的update方法', () => {
  const baseUpdateSpy = jest.spyOn(BaseStore.prototype, 'update');
  const store = new Store();
  
  store.increment();
  
  expect(baseUpdateSpy).toHaveBeenCalled();
});

二、测试属性在场景下的变化

这个就比较直接了——实例化类,执行对应操作后,直接断言属性值是否符合预期:

1. 同步场景的属性测试

还是用上面的increment方法举例:

test('调用increment后count属性应该加1', () => {
  const store = new Store();
  // 初始状态断言
  expect(store.count).toBe(0);
  
  store.increment();
  
  // 执行后的状态断言
  expect(store.count).toBe(1);
});

2. 异步场景的属性测试

如果Store有异步方法(比如请求数据后更新属性),记得用async/await或者done回调处理:

// 先给Store加个异步方法
class Store extends BaseStore {
  constructor() {
    super();
    this.data = null;
  }

  async fetchData() {
    const response = await fetch('/api/data');
    this.data = await response.json();
  }
}

// 测试异步方法的属性变化
test('fetchData执行后应该更新data属性', async () => {
  // mock全局的fetch方法,避免真实请求
  global.fetch = jest.fn(() =>
    Promise.resolve({
      json: () => Promise.resolve({ id: 1, name: 'test-data' })
    })
  );

  const store = new Store();
  await store.fetchData();
  
  expect(store.data).toEqual({ id: 1, name: 'test-data' });
  // 顺便断言fetch是否被正确调用
  expect(fetch).toHaveBeenCalledWith('/api/data');
});

三、处理继承类的小技巧

  • 如果父类有复杂的初始化逻辑,不想在测试中执行,可以直接mock整个父类:
jest.mock('./BaseStore', () => {
  return jest.fn().mockImplementation(() => {
    return { update: jest.fn() }; // 只返回需要的mock方法
  });
});

这样实例化Store时,父类的原逻辑不会被触发,避免干扰测试。

  • 如果只需要mock父类的某个特定方法,用spyOn就足够,不用完全mock整个类,这样测试会更贴近真实场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:48:52