Sinon шпионит за выражением функции

Можно ли заставить sinon следить за функциональными выражениями? Посмотрите этот код, например.

function one() { return 1; }
function two() { return 2; }
function three() { return 3; }

function myMethod() {
  var n1 = one();
  var n2 = two();
  var n3 = three();
  return n1 + n2 + n3;
}


QUnit.module('My test');

QUnit.test('testing functions', (assert) => {
  assert.expect(3);
  
  const spyOne = sinon.spy(one);
  const spyTwo = sinon.spy(two);
  const spyThree = sinon.spy(three);
	myMethod();

  assert.ok(spyOne.called, "called one");
  assert.ok(spyTwo.called, "called two");
  assert.ok(spyThree.called, "called three");
  
  sinon.restore();
});

Несмотря на то, что я звоню myMethod() и у меня есть шпионы на one - two - three, я все равно получаю ложный ответ на one.called (то же самое для two и three)

Что мне здесь не хватает?

Спасибо!


person Alejandro Nanez    schedule 07.05.2016    source источник


Ответы (1)


Вызов sinon.spy(fn) не меняет fn, он просто создает новую функцию (шпион), которая вызовет fn.

Чтобы вы могли протестировать one, two, three, вам нужно заменить эти функции (точнее, их ссылки) шпионами, а затем восстановить их:

// keep references to the original functions
var _one   = one;
var _two   = two;
var _three = three;

// replace the original functions with spies
one   = sinon.spy(one);
two   = sinon.spy(two);
three = sinon.spy(three);

// call our method
myMethod();

// test
assert.ok(one.called,   "called one");
assert.ok(two.called,   "called two");
assert.ok(three.called, "called three");

// restore the original functions
one   = _one;
two   = _two;
three = _three;

Однако это не идеально, и, если возможно, я бы, вероятно, сгруппировал все функции в объект. Это также позволило бы Синон самой восстановить оригиналы.

person robertklep    schedule 07.05.2016
comment
Это работает только в том случае, если у вас есть определения функций и тесты в одном файле, что бывает редко. - person Govind Rai; 29.01.2021
comment
@GovindRai правильно, но я не предлагаю решение этой конкретной проблемы. Я просто объясняю, почему исходный код в вопросе не работает должным образом и как это обойти. - person robertklep; 30.01.2021