Sinon Stub报错‘attempted to wrap undefined property...’,如何Stub测试含job变量的函数?
解决Sinon Stub报错“attempted to wrap undefined property of job as function”的方案
这个报错本质是Sinon找不到你要Stub的job变量——它在你试图包裹的对象上是undefined。我帮你拆解下常见原因和对应的解决办法:
1. 先确认job和job1是否正确导出
Sinon只能Stub外部能访问到的变量,如果job是myFunction.js里的局部私有变量,测试代码根本拿不到它,自然会报错。
比如你要确保myFunction.js里是这样导出的:
// myFunction.js // 直接导出函数 export const job = () => { return 'original job value'; }; export const job1 = () => { return 'original job1 value'; }; export function testFunction() { // 这里要直接使用导出的job/job1(ES模块导出的是引用,和局部变量指向同一个函数) return job() + job1(); }
如果之前是把job作为局部函数没导出,那必须先把它暴露出来,或者用后面提到的工具访问私有变量。
2. 正确导入模块并Stub导出的属性
很多人会犯的错是单独导入job然后Stub,这样Stub的是值的副本,根本不会影响testFunction里的调用。你需要导入整个模块对象,然后在这个对象上Stub:
// 测试文件 import * as myModule from './myFunction.js'; import sinon from 'sinon'; describe('testFunction', () => { it('should use stubbed job and job1 values', () => { // 在模块对象上Stub job和job1 const jobStub = sinon.stub(myModule, 'job').returns('我是Stub的job值'); const job1Stub = sinon.stub(myModule, 'job1').returns('我是Stub的job1值'); // 调用要测试的函数 const result = myModule.testFunction(); // 验证结果是否符合预期 expect(result).to.equal('我是Stub的job值我是Stub的job1值'); // 测试完恢复原函数,避免影响其他测试 jobStub.restore(); job1Stub.restore(); }); });
如果你的项目用CommonJS(Node.js风格)导出,写法类似:
// myFunction.js exports.job = () => { return 'original'; }; exports.job1 = () => { return 'original1'; }; exports.testFunction = function() { return exports.job() + exports.job1(); }; // 测试文件 const myModule = require('./myFunction.js'); const sinon = require('sinon'); // 同样在myModule对象上Stub即可
3. 如果job是私有变量(没法直接导出)
要是你不想把job暴露成导出变量,可以用rewire工具来访问模块内部的私有变量。它能让你修改模块里的局部变量,非常适合这种场景:
首先安装rewire(如果是ES模块可能需要配合babel插件):
npm install rewire --save-dev
然后测试代码里这么写:
const rewire = require('rewire'); const myModule = rewire('./myFunction.js'); const sinon = require('sinon'); describe('testFunction', () => { it('should stub private job and job1', () => { // 用rewire的__set__方法替换私有变量 const jobStub = sinon.stub().returns('Stub私有job'); myModule.__set__('job', jobStub); const job1Stub = sinon.stub().returns('Stub私有job1'); myModule.__set__('job1', job1Stub); const result = myModule.testFunction(); expect(result).to.equal('Stub私有jobStub私有job1'); }); });
4. 检查Karma的模块加载配置
如果以上都没问题还是报错,大概率是Karma没正确处理你的模块。比如你用ES6+语法,但没配置babel-loader或者webpack来转译,导致导入的模块对象不是预期的结构,job变成了undefined。
确保你的Karma配置里包含了处理ES模块的插件,比如karma-webpack配合babel-loader,或者karma-babel-preprocessor,让测试代码能正确识别模块导出。
内容的提问来源于stack exchange,提问作者ali 1214
相关产品推荐
相关产品推荐

