Jest测试未覆盖Callback function,如何对该回调进行Mock?
解决方案
覆盖赋值代码段
你要覆盖的twitterData.ready赋值逻辑,只会在两个前置条件同时满足时执行:
getDocumentDefaultView()返回非空值scriptExists()返回false,如果该方法返回true,代码会直接进入if分支提前return,跳过后续所有赋值逻辑
你现有测试未mockscriptExists()的返回值,大概率是该方法默认返回true,导致直接走了提前返回分支,自然覆盖不到目标代码。调整后的测试用例如下:
describe('startScriptLoad()', () => { it('should assign custom ready method to twitterData when script does not exist', () => { // mock前置依赖返回值 jest.spyOn(service, 'getDocumentDefaultView').mockReturnValue({} as any); jest.spyOn(service, 'scriptExists').mockReturnValue(false); jest.spyOn(service, 'appendScriptToDOM'); service.startScriptLoad(); expect(service.getDocumentDefaultView).toHaveBeenCalled(); expect(service.scriptExists).toHaveBeenCalled(); expect(service.appendScriptToDOM).toHaveBeenCalled(); // 验证全局挂载的twitter对象ready方法已被赋值 const twitterObj = (document.defaultView as any)[service.TWITTER_OBJECT]; expect(twitterObj.ready).toBeDefined(); expect(typeof twitterObj.ready).toBe('function'); }); });
执行该用例后,你提到的twitterData.ready = (callback: () => void) => {这行赋值代码就会被覆盖。
覆盖ready回调内部的push逻辑
如果还需要覆盖回调函数内部的twitterData._e.push(callback)代码,只需要主动调用全局挂载的twitter对象的ready方法即可,补充测试用例如下:
it('should push callback to _e array when ready method is called', () => { jest.spyOn(service, 'getDocumentDefaultView').mockReturnValue({} as any); jest.spyOn(service, 'scriptExists').mockReturnValue(false); const mockCallback = jest.fn(); service.startScriptLoad(); const twitterObj = (document.defaultView as any)[service.TWITTER_OBJECT]; // 主动调用ready方法触发内部push逻辑 twitterObj.ready(mockCallback); expect(twitterObj._e).toHaveLength(1); expect(twitterObj._e[0]).toBe(mockCallback); });
内容的提问来源于stack exchange,提问作者methuselah
相关产品推荐
相关产品推荐

