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

时间:2012-08-19 07:44:44

标签: javascript node.js mocha sinon

我正在使用sinon.js作为在Mocha测试中存根依赖关系的方法。我喜欢'间谍'方法而不是经典的模拟方法,因为间谍的内省看起来更清晰,并且提供了比经典模拟对象略微落后思考更多的灵活性。

那就是说,我想知道在创建整个对象的测试间谍时我是否正确使用它。假设我有一个测试依赖项,它有4个方法,我希望将每个方法存根并在其中的一个或两个上进行断言。目前我正在这样做:

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

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

之类的问题

是否有更好的方法来模拟整个类而不是重复测试套件本身的方法名称?看起来像sinon.stub()尝试遍历给定对象的所有成员,但这似乎不能作为一种方法来获取更现代的JS运行时(如V8)中的大多数对象的所有方法,除非该对象实际上是可以枚举的东西。它还尝试对实际对象进行修补,而不是返回等效的对象,这在某种程度上是不可取的。我只需要一个符合接口的对象,但行为就像一个null对象,除非我另有说明。

能够做类似的事情会很好:

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

如何在Node.js中找到构造函数/原型的所有方法,以便像上面那样创建一个包装器?

这更多是关于存根逻辑,而不是测试许多方法的调用(我试图限制为一个,或者推动两个)。例如,可能会执行不需要的I / O的操作,或者执行时需要额外的复杂装置。

2 个答案:

答案 0 :(得分:11)

从Sinon 1.6.0开始,您可以:

var stub = sinon.createStubInstance(MyClass)

请参阅Stub API sectionsource中的sinon.stub文档。

答案 1 :(得分:7)

我找到了一种方法:

/** 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