使用Sinon.js存根类方法


99

我正在尝试使用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/)。

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

Answers:


155

您的代码正在尝试在一个函数上存根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());

1
哪个东西不推荐使用?
loganfsmyth

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

那是我的答案,因为最初的问题专门询问了该问题。鉴于我的回答并未建议将其作为开始时的正确方法,因此我不确定您要我进行哪些更改。.returns(0)已经做与.callFake(() => 0)
loganfsmyth

1
似乎returns不建议弃用。sinonjs.org/releases/v3.0.0/stubs。@ danday74,请提供参考。
allenhwkim

2
删除.stub了带有函数作为第三个参数的@ danday74 :github.com/sinonjs/sinon/blob/master/lib/sinon/stub.js#L17.returns或没问题.callsFake,所以这个答案没有问题。
loganfsmyth

52

首选答案已过时。您现在应该使用:

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

或对于静态方法:

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

或者对于简单的情况,只需使用return即可:

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

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

或者,如果您想为实例添加方法:

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

4
这将是巨大的,如果你能提具体版本为您所述方法时,这是加入到sinonjscallsFake()此外,对于旧版本这可怎么过时?
aitchkhan

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

1
您的解决方案对我有用。希望我能给您更多点意见:D谢谢。
Rubel hasan

5

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

给定这样的课程:

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

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

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

# ...

assert.ok(mySpy.called)

只需替换spystubmock即可。

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


2

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

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

3
这是一条评论。首先感谢另一个答案,然后重复其代码。
michelpm 2015年

5
看起来并不像是重复-在这里Foo.prototype.constructor,就像在原始答案中一样Sensor.prototype。再说一次,Foo.prototype.constructor对我不起作用。:)
shaunc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.