2014-01-12 26 views
64

我试图用sinon.js存根的方法,但我得到了以下错误:打桩一个类的方法与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/)用于上面的代码,和所述的jsfiddle为SO问题,我提到(http://jsfiddle.net/pebreo/9mK5d/1/)。

我确保将sinon包含在jsFiddle和jQuery 1.9中的外部资源中。我究竟做错了什么?

回答

114

您的代码正试图在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()); 
+2

2017年,这已被弃用。您现在应该使用callsFake - 请参阅下面的答案。 – danday74

+0

弃用哪件东西? – loganfsmyth

+0

sinon.stub(Sensor,“sample_pressure”,function(){return 0}) – danday74

2

感谢@loganfsmyth的小费。我能得到存根上这样灰烬类方法的工作:

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

这是一条评论。首先感谢另一个答案,并以其代码的重复结束。 – michelpm

+4

看起来不像重复 - 这里有'Foo.prototype.constructor',在原始答案中有'Sensor.prototype'。然后再一次,'Foo.prototype.constructor'不适合我。 :) – shaunc

2

我碰到了同样的错误,试图用嘲弄一个兴农CoffeeScript的类的方法。

鉴于一类是这样的:

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

你可以用一个间谍取代其方法是这样的:

mySpy = sinon.spy(MyClass.prototype, "myMethod") 

# ... 

assert.ok(mySpy.called) 

只是stubmock更换spy需要。

请注意,您需要用您的测试框架拥有的任何声明替换assert.ok

13

最佳答案已弃用。您现在应该使用:

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({}) 
+1

此外,如果您可以在将此方法添加到'sinonjs',即'callsFake()' 以及更高版本时提及该方法的特定版本,那么对于旧版本,这怎么可能被弃用呢? –

+0

使用ES6模块时:我在测试项目中创建YourClass.get()的存根。测试调用另一个导入YourClass的模块。模块YourClass.get()会尊重存根吗?如果没有,是否有解决方案? – Learner