При тестировании нашего кода Javascript есть некоторые внешние переменные, которые иногда могут усложнить нам задачу. Как течение времени, например. Или, полагаясь на состояние внешнего сервера, который может не иметь ничего общего с функцией, которую мы пытаемся протестировать. К счастью, существует библиотека под названием Sinon, которая может абстрагироваться от части этой сложности, позволяя нам создавать то, что по сути является «тест-двойниками», которые могут помочь нам тестировать наш код независимо от этих внешних переменных.

«Тестовые двойники», которые предлагает Синон, называются шпионами и заглушками. Они оба могут предоставить нам полезную информацию о том, как ведут себя функции в нашем коде, например, сколько раз вызывалась определенная функция, или с какими аргументами вызывалась функция, или какие исключения возникали при каждом вызове. Основное различие между ними заключается в том, как они влияют на поведение функции.

Тестовый шпион записывает информацию о своих вызовах, но никак не меняет фактическое поведение функции. Мы бы использовали шпиона, если бы просто пытались собрать информацию о вызовах функции или метода, сохраняя при этом их естественное поведение.

С другой стороны, заглушки — это функции с заранее запрограммированным поведением. Мы будем использовать заглушки, когда хотим контролировать поведение метода из теста, чтобы заставить код идти по определенному пути, например, чтобы он целенаправленно выдавал ошибку, чтобы проверить обработку ошибок метода, или предотвратить прямой вызов определенного метода.

Еще одна чрезвычайно полезная функция, которую предлагает Sinon, — это возможность создания фальшивого таймера. Это может помочь нам тестировать части нашего кода, которые зависят от течения времени, и точно видеть, какие моменты времени оказываются проблемными. Примером этого может быть слежка за регулируемой функцией, наблюдение за тем, сколько раз она была вызвана за определенный промежуток времени:

beforeEach(function() {
callback = sinon.spy();
});
it('should return a function callable twice in the first 200ms', function() {
var fn = _.throttle(callback, 100);
fn(); // called
setTimeout(fn, 50);
setTimeout(fn, 100); // called
setTimeout(fn, 150);
setTimeout(fn, 199);
clock.tick(200);
expect(callback).to.have.been.calledTwice;
});

Мы настроили обратный вызов как функцию sinon.spy(). Затем мы ограничиваем эту шпионскую функцию. Мы запускаем несколько setTimeouts, а затем «тикаем» на часах, чтобы переместить наше смоделированное время вперед. На этом этапе мы можем точно установить, сколько раз был вызван наш шпион (или, если мы хотим, выяснить, с какими аргументами был вызван каждый вызов и т. д.).

Sinon предоставляет несколько полезных методов и утверждений, которые могут помочь нашим тестам стать намного более эффективными и автономными. Рассмотрите возможность использования Sinon в следующий раз, когда обнаружите, что ваши тесты слишком зависят от внешних факторов, и верните контроль над своими тестами!