Используйте sinon.js для создания шпионского объекта с помощью шпионских методов на основе реального конструктора/прототипа.

Я использую 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, если только объект на самом деле нечто перечислимое. Он также пытается исправить фактический объект, а не возвращать эквивалентный, что несколько нежелательно. Мне просто нужен объект, который соответствует интерфейсу, но ведет себя как нулевой объект, если я не скажу иначе.

Было бы хорошо иметь возможность сделать что-то вроде:

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

Как найти все методы конструктора/прототипа в Node.js, чтобы сделать оболочку, подобную приведенной выше?

Это больше связано с заглушением логики, чем с тестированием вызовов множества методов (которые я стараюсь ограничить одним или сразу двумя). Например, вещи, которые могут привести к нежелательному вводу-выводу или потребовать дополнительных сложных приспособлений, если они выполняются.


person d11wtq    schedule 19.08.2012    source источник


Ответы (2)


Начиная с Sinon 1.6.0 вы можете:

var stub = sinon.createStubInstance(MyClass)

См. документацию по sinon.stub в разделе API-заглушек или источник.

person tfischbach    schedule 26.09.2013
comment
Ссылка, ведущая на страницу обзора документации: sinonjs.org/releases/v2. 3.4/stubs/#stub-api работает в настоящее время - person sschoof; 12.06.2017

Я нашел способ сделать это:

/** 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
person d11wtq    schedule 20.08.2012
comment
Это может быть полезно иметь в источнике sinon. - person jcollum; 18.02.2013