【问题标题】:Stubbing a class method with Sinon.js使用 Sinon.js 存根类方法
【发布时间】:2014-01-31 01:28:09
【问题描述】:

我正在尝试使用 sinon.js 对方法进行存根,但出现以下错误:

Uncaught TypeError: Attempted to wrap undefined property sample_pressure as function

我也去了这个问题 (Stubbing and/or mocking a class in sinon.js?) 并复制并粘贴了代码,但我得到了同样的错误。

这是我的代码:

Sensor = (function() {
  // A simple Sensor class

  // Constructor
  function Sensor(pressure) {
    this.pressure = pressure;
  }

  Sensor.prototype.sample_pressure = function() {
    return this.pressure;
  };

  return Sensor;

})();

// Doesn't work
var stub_sens = sinon.stub(Sensor, "sample_pressure").returns(0);

// Doesn't work
var stub_sens = sinon.stub(Sensor, "sample_pressure", function() {return 0});

// Never gets this far
console.log(stub_sens.sample_pressure());

这是上面代码的 jsFiddle (http://jsfiddle.net/pebreo/wyg5f/5/),以及我提到的 SO 问题的 jsFiddle (http://jsfiddle.net/pebreo/9mK5d/1/)。

我确保在 jsFiddle 甚至 jQuery 1.9 的 External Resources 中包含 sinon。我做错了什么?

【问题讨论】:

    标签: javascript node.js sinon


    【解决方案1】:

    不推荐使用最佳答案。您现在应该使用:

    sinon.stub(YourClass.prototype, 'myMethod').callsFake(() => {
        return {}
    })
    

    或者对于静态方法:

    sinon.stub(YourClass, 'myStaticMethod').callsFake(() => {
        return {}
    })
    

    或者对于简单的情况,只需使用返回:

    sinon.stub(YourClass.prototype, 'myMethod').returns({})
    
    sinon.stub(YourClass, 'myStaticMethod').returns({})
    

    或者如果你想为一个实例存根一个方法:

    const yourClassInstance = new YourClass();
    sinon.stub(yourClassInstance, 'myMethod').returns({})
    

    【讨论】:

    • 使用 ES6 模块时:我正在测试项目中创建 YourClass.get() 的存根。测试调用另一个导入 YourClass 的模块。模块 YourClass.get() 会尊重存根吗?如果没有,有解决办法吗?
    • 您的解决方案对我有用。我希望我能给你更多的分数:D 谢谢。
    【解决方案2】:

    我在尝试使用 Sinon 模拟 CoffeeScript 类的方法时遇到了同样的错误。

    给定这样的课程:

    class MyClass
      myMethod: ->
        # do stuff ...
    

    您可以通过这种方式将其方法替换为间谍:

    mySpy = sinon.spy(MyClass.prototype, "myMethod")
    
    # ...
    
    assert.ok(mySpy.called)
    

    只需根据需要将spy 替换为stubmock

    请注意,您需要将 assert.ok 替换为您的测试框架具有的任何断言。

    【讨论】:

      【解决方案3】:

      感谢@loganfsmyth 的提示。我能够让存根在这样的 Ember 类方法上工作:

      sinon.stub(Foo.prototype.constructor, 'find').returns([foo, foo]);
      expect(Foo.find()).to.have.length(2)
      

      【讨论】:

      • 这是一条评论。以感谢另一个答案开始,以重复其代码结束。
      • 看起来不像是重复的——这里是Foo.prototype.constructor,而在原始答案中是Sensor.prototype。再说一次,Foo.prototype.constructor 对我不起作用。 :)
      【解决方案4】:

      您的代码正试图在 Sensor 上存根函数,但您已在 Sensor.prototype 上定义了该函数。

      sinon.stub(Sensor, "sample_pressure", function() {return 0})
      

      本质上和这个是一样的:

      Sensor["sample_pressure"] = function() {return 0};
      

      但它足够聪明地看到Sensor["sample_pressure"] 不存在。

      所以你想做的是这样的:

      // Stub the prototype's function so that there is a spy on any new instance
      // of Sensor that is created. Kind of overkill.
      sinon.stub(Sensor.prototype, "sample_pressure").returns(0);
      
      var sensor = new Sensor();
      console.log(sensor.sample_pressure());
      

      // Stub the function on a single instance of 'Sensor'.
      var sensor = new Sensor();
      sinon.stub(sensor, "sample_pressure").returns(0);
      
      console.log(sensor.sample_pressure());
      

      // Create a whole fake instance of 'Sensor' with none of the class's logic.
      var sensor = sinon.createStubInstance(Sensor);
      console.log(sensor.sample_pressure());
      

      【讨论】:

      • 哪些东西被弃用了?
      • sinon.stub(Sensor, "sample_pressure", function() {return 0})
      • 这是我的回答,因为原始问题专门询问了它。鉴于我的回答并不表明它是开始的正确方法,我不确定你要我改变什么。 .returns(0) 已经和.callFake(() => 0) 做了同样的事情。
      • returns 似乎没有被弃用。 sinonjs.org/releases/v3.0.0/stubs。 @danday74,请提供参考。
      • @danday74 .stub 去掉了作为第三个参数的函数:github.com/sinonjs/sinon/blob/master/lib/sinon/stub.js#L17 .returns.callsFake 没有错,所以这个答案没有错。跨度>
      猜你喜欢
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 2020-07-01
      • 2016-08-16
      • 1970-01-01
      • 2016-09-17
      • 2017-07-12
      • 2012-01-09
      相关资源
      最近更新 更多