使用sinon.js创build一个基于真正的构造函数/原型的间谍方法的“间谍对象”

我正在使用sinon.js作为在我的Mochatesting中剔除依赖项的一种方法。 我更喜欢“间谍”方式,而不是经典的模拟方法,因为对间谍的反思似乎更清晰,并且比经典的模拟对象有些落后的思维更具灵活性。

这就是说,我想知道是否在为整个对象创buildtesting间谍时不正确地使用它。 比方说,我有一个testing依赖关系,它有4个方法,我想存根每个这些方法,并断言其中一个或两个。 目前我正在这样做:

var spyObj = { aMethod: sinon.spy(), otherMethod: sinon.spy(), whatever: sinon.spy() }; 

然后,我只是问像spyObj.aMethod.calledWith(a, b, c)

有没有更好的方法来模拟出整个类,而不是重复testing套件本身的方法的名称? 它看起来像sinon.stub()试图遍历给定的对象的所有成员,但这似乎并没有工作的方式来获取大多数对象的所有方法在更现代的JS运行时,如V8,除非对象实际上是可枚举的东西。 它也尝试猴子补丁的实际对象,而不是返回一个等价的,这是不可取的。 我只需要一个符合接口的对象,但行为像一个空对象,除非我另外说。

能够做这样的事情会很好:

 var spyObject = sinon.spy(MyClass.prototype); 

如何在Node.js中find构造函数/原型的所有方法,以便制作如上所述的包装?

这更多的是关于剔除逻辑,而不是testing调用许多方法(我试图限制到一个,或在一个推二)。 例如,可能做不需要的I / O的事情,或者如果执行,则需要额外的复杂装置。

从Sinon 1.6.0开始,你可以这样做:

 var stub = sinon.createStubInstance(MyClass) 

请参阅Stub API部分或源文件中的sinon.stub文档。

我find了一个方法来做到这一点:

 /** Accept a prototype and return a full stub object */ function stub(obj, target) { var cls = (typeof obj == 'function') ? obj.prototype : obj; target = target || {}; Object.getOwnPropertyNames(cls).filter(function(p){ return typeof cls[p] == 'function'; }).forEach(function(p) { target[p] = sinon.stub() }); return cls.__proto__ ? stub(cls.__proto__, target) : target; }; 

像这样使用它:

 var response = stub(http.ServerResponse); response.getHeader.withArgs('X-Foo').returns('bob'); response.getHeader.withArgs('X-Bar').returns('barry'); console.log(response.getHeader('X-Foo')); // bob console.log(response.getHeader('X-Bar')); // barry