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

