Шпионы — это функции, которые позволяют отслеживать вызовы других функций в процессе тестирования, не изменяя их поведение. В Mocha шпионы могут быть полезны для проверки того, были ли вызваны определённые методы, какие аргументы были переданы, а также для анализа результатов этих вызовов. Mocha не предоставляет собственных инструментов для создания шпионов, однако это можно сделать с помощью библиотеки Sinon, которая отлично интегрируется с Mocha и является стандартом де-факто для мокирования, шпионов и стабов в JavaScript.
Для того чтобы начать использовать шпионов, необходимо сначала установить и подключить Sinon. Сначала можно установить Sinon с помощью npm:
npm install --save-dev sinon
После установки, в коде теста, необходимо импортировать Sinon:
const sinon = require('sinon');
Теперь можно создавать шпионов, которые будут отслеживать вызовы функций.
Для того чтобы создать шпион на функцию, достаточно использовать
sinon.spy():
const myObject = {
myMethod: function (x, y) {
return x + y;
}
};
describe('Шпион для функции', function () {
it('должен отслеживать вызовы функции', function () {
const spy = sinon.spy(myObject, 'myMethod');
myObject.myMethod(2, 3);
// Проверка, что метод был вызван
sinon.assert.calledOnce(spy);
// Проверка аргументов, с которыми был вызван метод
sinon.assert.calledWith(spy, 2, 3);
});
});
В примере выше создается шпион для метода myMethod
объекта myObject. После вызова функции, можно проверить с
помощью sinon.assert такие моменты, как:
Шпион можно создать не изменяя оригинальную функцию, что особенно полезно для проверки сторонних библиотек или встроенных методов, где нельзя изменить поведение:
const spy = sinon.spy();
spy(1, 2, 3);
// Проверка вызова
sinon.assert.calledOnce(spy);
// Проверка аргументов
sinon.assert.calledWith(spy, 1, 2, 3);
В этом примере создается шпион, который отслеживает вызовы на стандартной функции, и сразу же проверяется, был ли вызван этот шпион с нужными аргументами.
После завершения теста, важно удалить шпиона, чтобы избежать влияния
на другие тесты. Для этого можно использовать метод
restore():
myObject.myMethod.restore();
Эта операция восстанавливает оригинальную функцию, которая была шпионена.
Кроме проверки того, с какими аргументами был вызван метод, также можно проверять количество вызовов:
const spy = sinon.spy();
spy();
spy();
spy();
sinon.assert.callCount(spy, 3); // Проверка, что метод был вызван 3 раза
Метод callCount позволяет точно узнать, сколько раз была
вызвана функция, на которой установлен шпион.
Шпионов можно использовать не только для простых функций, но и для методов объектов или классов. Например, можно создать шпион для метода класса:
class MyClass {
doSomething(x) {
return x * 2;
}
}
describe('Шпион для метода класса', function () {
it('должен отслеживать вызов метода', function () {
const myInstance = new MyClass();
const spy = sinon.spy(myInstance, 'doSomething');
myInstance.doSomething(5);
sinon.assert.calledOnce(spy);
sinon.assert.calledWith(spy, 5);
});
});
Шпионы также можно использовать для асинхронных функций. Например, если у вас есть функция, которая выполняет асинхронную задачу, можно проверить, был ли вызван callback или промис:
const asyncFunction = function (callback) {
setTimeout(function () {
callback('done');
}, 100);
};
describe('Шпион для асинхронной функции', function () {
it('должен отслеживать вызов callback', function (done) {
const spy = sinon.spy();
asyncFunction(spy);
setTimeout(function () {
sinon.assert.calledOnce(spy);
sinon.assert.calledWith(spy, 'done');
done();
}, 150);
});
});
Временные функции, такие как setTimeout или
setInterval, можно также шпионить, чтобы тестировать их
поведение. Например, можно проверить, был ли вызван таймер с нужными
параметрами:
describe('Шпион для setTimeout', function () {
it('должен отслеживать вызов setTimeout', function () {
const spy = sinon.spy();
const timer = setTimeout(spy, 100);
clearTimeout(timer);
sinon.assert.notCalled(spy);
});
});
Шпион может также быть использован для модификации поведения отслеживаемой функции. Для этого можно передать функцию, которая будет выполняться вместо оригинальной:
const spy = sinon.spy(function () {
return 'modified';
});
console.log(spy()); // 'modified'
Это полезно, если нужно протестировать поведение функции без вызова оригинальной логики.
Шпионы в Mocha, используя библиотеку Sinon, предоставляют мощный инструмент для тестирования вызовов функций, проверки их аргументов и поведения. Это особенно полезно при работе с сторонними библиотеками или при тестировании функций, которые зависят от внешних факторов. Помимо стандартных функций, шпионы поддерживают работу с асинхронными задачами и временными функциями, что делает их универсальными для различных типов тестов.