使用Sinon Stub测试对象方法未生效,求助排查问题
问题分析与解决
问题场景
代码文件someFile.js结构如下:
import someService from 'a-location'; const val = someService.getVal(); const AnObject = { someMethod() { if(val) // 执行相关逻辑 } } export default AnObject;
测试文件代码:
import someService from 'a-location'; import AnObject from 'someFile'; describe("测试描述", function(){ it('具体测试点', function() { sinon.stub(someService, 'getVal').returns('my-val'); AnObject.someMethod(); }) })
你期望someFile.js中调用someService.getVal()时能拿到'my-val',但没达到预期,问题出在这:
错误根源
val是在模块刚加载的时候就调用someService.getVal()完成赋值的。你的测试代码是先导入AnObject(此时模块已经加载完成,val已经是原getVal的返回值),之后才给getVal打桩,这时候打桩根本影响不到已经赋值好的val。
两种修复方案
方案一:延迟调用时机
把val的赋值移到someMethod内部,这样每次调用方法时才会去执行getVal(),自然会被stub拦截:
import someService from 'a-location'; const AnObject = { someMethod() { const val = someService.getVal(); if(val) // 执行相关逻辑 } } export default AnObject;
方案二:先打桩再导入模块
调整测试代码的顺序,先给getVal打桩,再导入AnObject,这样模块加载时就会用stub后的返回值给val赋值:
import someService from 'a-location'; // 先打桩 sinon.stub(someService, 'getVal').returns('my-val'); // 再导入模块 import AnObject from 'someFile'; describe("测试描述", function(){ it('具体测试点', function() { AnObject.someMethod(); }) })
注意:如果用的是ES模块,部分测试框架可能需要配合proxyquire或rewire这类工具来实现导入前的依赖替换,确保打桩能覆盖模块加载阶段的调用。
内容的提问来源于stack exchange,提问作者RamKris
相关产品推荐
相关产品推荐

