You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:55:23