NetSuite SuiteScript中Jest Mock同模块函数失败的解决方法
问题分析与解决思路
你的测试失败核心原因是:模块内部afterSubmit调用的是原始的foo函数声明,而你通过jest.spyOn(ueScript, 'foo')监视的是导出对象上的foo属性——这两者指向的调用路径不同,所以spy无法捕获内部的函数调用。
解决方法
方法一:调整源代码的内部调用逻辑(推荐)
修改模块内部的函数引用方式,让afterSubmit调用的是与导出对象共享的foo引用,这样spy替换导出对象的foo后,内部调用也会指向被mock的函数。
修改后的源代码:
/** * @NApiVersion 2.1 * @NScriptType UserEventScript */ define([],() => { // 将函数挂载到导出对象上,内部调用该对象的方法 const exports = { afterSubmit(scriptContext) { try { if(scriptContext.type === 'create'){ exports.foo(); // 调用导出对象上的foo,而非原始函数声明 } } catch (error) { log.error('afterSubmit', error); } }, foo() { //do sth... } }; return exports; });
此时你的原有测试代码无需修改,运行后即可正确捕获foo的调用。
方法二:补充NetSuite全局对象的Mock(必要步骤)
测试时还需要mock NetSuite的log全局对象,否则会因找不到log.error而报错,在测试文件顶部添加:
// Mock NetSuite的log全局对象 global.log = { error: jest.fn() };
同时建议在beforeEach中清除mock的调用记录,避免测试用例间的干扰:
beforeEach(() => { jest.clearAllMocks(); });
最终完整的测试文件:
import * as ueScript from 'the file path' // Mock NetSuite log module global.log = { error: jest.fn() }; describe('Check run situation',()=>{ const MOCK_SCRIPT_CONTEXT = {}; beforeEach(() => { jest.clearAllMocks(); }); it('Should call foo when type is create',()=>{ jest.spyOn(ueScript, 'foo'); MOCK_SCRIPT_CONTEXT.type = 'create'; ueScript.afterSubmit(MOCK_SCRIPT_CONTEXT); expect(ueScript.foo).toHaveBeenCalled(); }); });
内容的提问来源于stack exchange,提问作者Steven Chao
相关产品推荐
相关产品推荐

