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

如何使用Sinon Mock以this关键字定义的函数?测试报错求解

解决Mocha+Sinon测试时无法Stub doRandomStuff的问题

你遇到的报错TypeError: Cannot stub non-existent own property doRandomStuff,核心原因是你定义doRandomStuff的方式导致Sinon无法正确识别这个属性:

在你的foo构造函数里,doRandomStuff是每个实例创建时才动态添加到this上的自有属性,而不是挂载在foo.prototype上的原型方法。这种情况下,直接Stub实例或构造函数本身的doRandomStuff都会失效,原因如下:

  • sinon.stub(instance,'doRandomStuff'):理论上创建实例后这个属性应该存在,但Sinon对动态添加的自有属性的检测逻辑,可能导致识别失败;
  • sinon.stub(foo,'doRandomStuff'):你Stub的是构造函数foo本身的属性,而不是实例的属性——实例创建时会重新给this.doRandomStuff赋值,完全不受这个Stub影响。

下面提供两种可行的解决办法:


方法一:重构foo,将方法挂载到原型上(推荐)

这种方式不仅让测试更简单,也符合JS的原型链最佳实践,避免每个实例都创建重复的函数:

// 修改原foo的定义
var foo = function(){};
// 将doRandomStuff放到原型上
foo.prototype.doRandomStuff = function(callback){
  // do Something
  callback(false);
};

对应的测试代码可以这样写:

describe("Foo Test", function(){
  it("testing foo", function(done){
    // Stub原型上的doRandomStuff方法,指定回调参数为true
    const doRandomStuffStub = sinon.stub(foo.prototype, 'doRandomStuff').callsArgWith(0, true);
    
    bar();
    
    // 验证方法是否被调用
    sinon.assert.calledOnce(doRandomStuffStub);
    
    // 恢复原型方法,避免影响其他测试用例
    doRandomStuffStub.restore();
    done();
  });
});

方法二:不修改原代码,Stubfoo构造函数返回假实例

如果不能改动原业务代码,可以通过Sinon替换foo构造函数,让它返回一个预定义好Stub方法的假实例:

describe("Foo Test", function(){
  it("testing foo", function(done){
    // 创建假的foo实例,包含Stub后的doRandomStuff
    const fakeFooInstance = {
      doRandomStuff: sinon.stub().callsArgWith(0, true)
    };
    
    // 替换全局的foo构造函数,让它返回假实例
    const fooConstructorStub = sinon.stub(window, 'foo').returns(fakeFooInstance);
    
    try {
      bar();
      // 验证doRandomStuff是否被正确调用
      sinon.assert.calledOnce(fakeFooInstance.doRandomStuff);
    } finally {
      // 必须恢复原构造函数,否则会影响其他测试
      fooConstructorStub.restore();
    }
    
    done();
  });
});

这样当bar函数里执行new foo()时,得到的是我们的假实例,它的doRandomStuff方法会按预期调用回调并传入true,完美满足测试需求。


内容的提问来源于stack exchange,提问作者Mukesh Verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:20:55