使用 Sinon.js 修补类方法

我尝试使用 sinon.js 来存根一个方法,但是我得到了以下错误:

Uncaught TypeError: Attempted to wrap undefined property sample_pressure as function

我也去这个问题(在 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中的 外部资源中包含了 sinon?

111553 次浏览

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

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

is essentially the same as this:

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

but it is smart enough to see that Sensor["sample_pressure"] doesn't exist.

你可以这样做:

// 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());

Thanks to @loganfsmyth for the tip. I was able to get the stub to work on an Ember class method like this:

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

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

给一个这样的班级:

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

你可以用间谍代替它的方法:

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


# ...


assert.ok(mySpy.called)

只需根据需要将 spy替换为 stubmock即可。

请注意,您需要使用测试框架中的任何断言来替换 assert.ok

最上面的答案是不推荐的,现在应该使用:

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