Заглушки
Что такое заглушки?
Заглушки — это функции (шпионы) с запрограммированным поведением.
Они поддерживают полный API шпионов помимо методов, которые могут быть использованы для изменения поведения заглушки.
В качестве шпионов заглушки могут быть анонимными или оборачивать существующие функции. При обертывании существующей функции заглушкой, исходная функция не вызывается.
Когда использовать заглушки?
Используйте заглушку, когда хотите:
-
Управлять поведением метода из теста, чтобы принудительно направить код по определенному пути. Примеры включают принуждение метода к сбросу ошибки для проверки обработки ошибок.
-
Когда нужно предотвратить прямой вызов конкретного метода (возможно, потому что он вызывает нежелательное поведение, например,
XMLHttpRequestили подобное).
Следующий пример — еще один тест из PubSubJS, который демонстрирует, как создать анонимную заглушку, которая выбрасывает исключение при вызове.
Обратите внимание, как заглушка также реализует интерфейс шпиона. Тест проверяет, что все обратные вызовы были вызваны, а также что заглушка, выбрасывающая исключение, была вызвана до одного из других обратных вызовов.
Определение поведения заглушки при последовательных вызовах
Вызов методов определения поведения, таких как returns или throws, несколько раз перезаписывает поведение заглушки. Начиная с версии Sinon 1.8, можно использовать метод onCall, чтобы заглушка реагировала по-разному при последовательных вызовах.
Обратите внимание, что в версиях Sinon с 1.5 по 1.7 несколько вызовов семейства методов yields* и callsArg* определяют последовательность поведения для последовательных вызовов. Начиная с версии 1.8, эта функциональность была удалена в пользу API onCall.
API заглушки
Свойства
var stub = sinon.stub();
Создает анонимную функцию-заглушку
var stub = sinon.stub(object, "method");
Заменяет object.method функцией-заглушкой. Если свойство не является функцией, выбрасывается исключение.
Исходную функцию можно восстановить, вызвав object.method.restore(); (или stub.restore();).
var stub = sinon.stub(object, "method", func);
var stub = sinon.stub(object, "method", func);Это было удалено из v3.0.0. Вместо этого вы должны использовать
stub(obj, 'meth').callsFake(fn)
Доступен кодмод для обновления вашего кода
var stub = sinon.stub(obj);
Заглушает все методы объекта.
Обратите внимание, что обычно лучше заглушать отдельные методы, особенно для объектов, которые вы не понимаете или не контролируете все методы (например, зависимости библиотек).
Заглушение отдельных методов более точно тестирует намерение и менее подвержено неожиданному поведению по мере развития кода объекта.
Если вы хотите создать объект-заглушку для MyConstructor, но не хотите вызывать конструктор, используйте эту вспомогательную функцию.
var stub = sinon.createStubInstance(MyConstructor, overrides);
overrides — это необязательная карта, переопределяющая созданные заглушки, например:
var stub = sinon.createStubInstance(MyConstructor, {
foo: sinon.stub().returnsThis()
});
равносильно:
var stub = sinon.createStubInstance(MyConstructor); stub.foo.returnsThis();
Если предоставленное значение не является заглушкой, оно будет использовано в качестве возвращаемого значения:
var stub = sinon.createStubInstance(MyConstructor, {
foo: 3
});
равносильно:
var stub = sinon.createStubInstance(MyConstructor); stub.foo.returns(3);
stub.withArgs(arg1[, arg2, ...]);
Заглушает метод только для предоставленных аргументов.
Это полезно для более выразительных утверждений, где вы можете получить доступ к шпиону с тем же вызовом. Это также полезно для создания заглушки, которая может действовать по-разному в ответ на разные аргументы.
Используется глубокое сравнение для объектов и массивов. Используйте stub.withArgs(sinon.match.same(obj)) для строгого сравнения (см. сопоставители).
stub.onCall(n); Добавлено в v1.8
Определяет поведение заглушки при n-м вызове. Полезно для тестирования последовательных взаимодействий.
Есть методы onFirstCall, onSecondCall, onThirdCall для более естественного чтения определений заглушки.
onCall можно комбинировать со всеми методами определения поведения в этом разделе. В частности, его можно использовать вместе с withArgs.
Обратите внимание, как поведение заглушки для аргумента 42 возвращается к поведению по умолчанию после того, как больше вызовов не определено.
stub.onFirstCall();
Псевдоним для stub.onCall(0);
stub.onSecondCall();
Псевдоним для stub.onCall(1);
stub.onThirdCall();
Псевдоним для stub.onCall(2);
stub.reset();
Сбрасывает как поведение, так и историю заглушки.
Это эквивалентно вызову stub.resetBehavior() и stub.resetHistory().
Обновлено в sinon@2.0.0
С sinon@5.0.0
Для удобства вы можете применить stub.reset() ко всем заглушкам, используя sinon.reset()
stub.resetBehavior();
Сбрасывает поведение заглушки до значения по умолчанию
С sinon@5.0.0
Вы можете сбросить поведение всех заглушек, используя sinon.resetBehavior()
stub.resetHistory();
С sinon@2.0.0
Сбрасывает историю заглушки
С sinon@5.0.0
Вы можете сбросить историю всех заглушек, используя sinon.resetHistory()
stub.callsFake(fakeFunction);
Заставляет заглушку вызывать предоставленную fakeFunction при вызове.
stub.returns(obj);
Заставляет заглушку возвращать предоставленное значение.
stub.returnsArg(index);
Заставляет заглушку возвращать аргумент по предоставленному индексу.
stub.returnsArg(0); заставляет заглушку возвращать первый аргумент.
Если аргумент по предоставленному индексу недоступен, до sinon@6.1.2, будет возвращено значение undefined; начиная с sinon@6.1.2, будет выброшено исключение TypeError.
stub.returnsThis();
Заставляет заглушку возвращать её this значение.
Полезно для заглушения jQuery-подобных флюидных API.
stub.resolves(value);
Заставляет заглушку возвращать Promise, который разрешается предоставленным значением.
При построении Promise, sinon использует метод Promise.resolve. Вы несете ответственность за предоставление полифила в средах, которые не предоставляют Promise. Библиотеку Promise можно переопределить, используя метод usingPromise.
С sinon@2.0.0
stub.resolvesArg(index);
Заставляет заглушку возвращать Promise, который разрешается аргументом по предоставленному индексу.
stub.resolvesArg(0); заставляет заглушку возвращать Promise, который разрешается первым аргументом.
Если аргумент по предоставленному индексу недоступен, будет выброшено исключение TypeError.
С sinon@6.1.1
stub.throws();
Заставляет заглушку сбрасывать исключение (Error).
stub.throws("name"[, "optional message"]);
Заставляет заглушку сбрасывать исключение с свойством name, установленным на предоставленную строку. Параметр message является необязательным и установит свойство message исключения.
stub.throws(obj);
Заставляет заглушку сбрасывать предоставленный объект исключения.
stub.throws(function() { return new Error(); });
Заставляет заглушку сбрасывать исключение, возвращенное функцией.
stub.throwsArg(index);
Заставляет заглушку сбрасывать аргумент по предоставленному индексу.
stub.throwsArg(0); заставляет заглушку сбрасывать первый аргумент как исключение.
Если аргумент по предоставленному индексу недоступен, будет выброшено исключение TypeError.
С sinon@2.3.0
stub.rejects();
Заставляет заглушку возвращать Promise, который отклоняется с исключением (Error).
При построении Promise, sinon использует метод Promise.reject. Вы несете ответственность за предоставление полифила в средах, которые не предоставляют Promise. Библиотеку Promise можно переопределить, используя метод usingPromise.
С sinon@2.0.0
stub.rejects("TypeError");
Заставляет заглушку возвращать Promise, который отклоняется с исключением указанного типа.
С sinon@2.0.0
stub.rejects(value);
Заставляет заглушку возвращать Promise, который отклоняется с предоставленным объектом исключения.
С sinon@2.0.0
stub.callsArg(index);
Заставляет заглушку вызывать аргумент по предоставленному индексу как функцию обратного вызова.
stub.callsArg(0); заставляет заглушку вызывать первый аргумент как обратный вызов.
Если аргумент по предоставленному индексу недоступен или не является функцией, будет выброшено исключение TypeError.
stub.callThrough();
Заставляет исходный метод, обернутый в заглушку, вызываться, если ни одна из условных заглушек не соответствует.
stub.callThroughWithNew();
Заставляет исходный метод, обернутый в заглушку, вызываться с использованием оператора new при несовпадении ни одной из условных заглушек.
stub.callsArgOn(index, context);
Как stub.callsArg(index);, но с дополнительным параметром для передачи контекста this.
stub.callsArgWith(index, arg1, arg2, ...);
Как callsArg, но с аргументами для передачи в обратный вызов.
stub.callsArgOnWith(index, context, arg1, arg2, ...);
Как выше, но с дополнительным параметром для передачи контекста this.
stub.usingPromise(promiseLibrary);
Заставляет заглушку возвращать Promises, используя определенную библиотеку Promise вместо глобальной, при использовании stub.rejects или stub.resolves Возвращает заглушку для возможности цепочки.
С sinon@2.0.0
stub.yields([arg1, arg2, ...])
Аналогично callsArg.
Заставляет заглушку вызывать первый принятый обратный вызов с предоставленными аргументами (если таковые имеются).
Если метод принимает более одного обратного вызова, вам необходимо использовать yieldsRight для вызова последнего обратного вызова или callsArg для вызова других обратных вызовов, кроме первого или последнего.
stub.yieldsRight([arg1, arg2, ...])
Как yields но вызывает последний полученный обратный вызов.
stub.yieldsOn(context, [arg1, arg2, ...])
Как yields, но с дополнительным параметром для передачи this контекста.
stub.yieldsTo(property, [arg1, arg2, ...])
Приводит шпион к вызову коллбека, переданного как свойство объекта шпиону.
Как yields, yieldsTo захватывает первый соответствующий аргумент, находит коллбек и вызывает его с (необязательными) аргументами.
"test should fake successful ajax request": function () {
sinon.stub(jQuery, "ajax").yieldsTo("success", [1, 2, 3]);
jQuery.ajax({
success: function (data) {
assertEquals([1, 2, 3], data);
}
});
}
stub.yieldsToOn(property, context, [arg1, arg2, ...])
Аналогично вышеперечисленному, но с дополнительным параметром для передачи this контекста.
stub.yield([arg1, arg2, ...])
Вызывает коллбеки, переданные stub, с заданными аргументами.
Если подстановка никогда не вызывалась с аргументом-функцией, yield генерирует ошибку.
Возвращает массив со всеми значениями возврата коллбеков в порядке их вызова, если ошибка не генерируется.
Также известен как invokeCallback.
stub.yieldTo(callback, [arg1, arg2, ...])
Вызывает коллбеки, переданные как свойство объекта подстановке.
Как yield, yieldTo захватывает первый соответствующий аргумент, находит коллбек и вызывает его с (необязательными) аргументами.
stub.callArg(argNum)
Аналогично yield, но с явным номером аргумента, указывающим, какой коллбек вызывать.
Полезно, если функция вызывается с более чем одним коллбеком и нежелательно вызывать первый коллбек.
"calling the last callback": function () {
var callback = sinon.stub();
callback(function () {
console.log("Success!");
}, function () {
console.log("Oh noes!");
});
callback.callArg(1); // Logs "Oh noes!"
}
stub.callArgWith(argNum, [arg1, arg2, ...])
Аналогично callArg, но с аргументами.
Асинхронные вызовы
То же самое, что и соответствующие им вызовы без Async, но с отложенным коллбеком, вызываемым после обработки всех инструкций в текущей стеке вызовов.
- В среде Node коллбек откладывается с помощью
process.nextTick. - В браузере коллбек откладывается с помощью
setTimeout(callback, 0).
Дополнительная информация:
- https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick,
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop,
- https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout.
stub.callsArgAsync(index);
Асинхронная версия stub.callsArg(index). Смотрите также Асинхронные вызовы.
stub.callsArgOnAsync(index, context);
Асинхронная версия stub.callsArgOn(index, context). Смотрите также Асинхронные вызовы.
stub.callsArgWithAsync(index, arg1, arg2, ...);
Асинхронная версия stub.callsArgWith(index, arg1, arg2, …). Смотрите также Асинхронные вызовы.
stub.callsArgOnWithAsync(index, context, arg1, arg2, ...);
Асинхронная версия stub.callsArgOnWith(index, context, arg1, arg2, …). Смотрите также Асинхронные вызовы.
stub.yieldsAsync([arg1, arg2, ...]);
Асинхронная версия stub.yields([arg1, arg2, …]). Смотрите также Асинхронные вызовы.
stub.yieldsOnAsync(context, [arg1, arg2, ...]);
Асинхронная версия stub.yieldsOn(context, [arg1, arg2, …]). Смотрите также Асинхронные вызовы.
stub.yieldsToAsync(property, [arg1, arg2, ...]);
Асинхронная версия stub.yieldsTo(property, [arg1, arg2, …]). Смотрите также Асинхронные вызовы.
stub.yieldsToOnAsync(property, context, [arg1, arg2, ...])
Асинхронная версия stub.yieldsToOn(property, context, [arg1, arg2, …]). Смотрите также Асинхронные вызовы.
sinon.addBehavior(name, fn);
Добавить пользовательское поведение. Имя будет доступно как функция в подстановках, и механизм цепочки вызовов будет настроен за вас (например, вам не нужно возвращать ничего из вашей функции, ее значение возврата будет проигнорировано). fn будет передан фейковый экземпляр как первый аргумент, а затем аргументы пользователя.
stub.get(getterFn)
Заменяет новый геттер для этой подстановки.
stub.set(setterFn)
Определяет новый сеттер для этой подстановки.
stub.value(newVal)
Определяет новое значение для этой подстановки.
Вы можете восстановить значения, вызвав метод restore:
stub.wrappedMethod
Содержит ссылку на исходный метод/функцию, которую эта подстановка обернула. undefined для доступа к свойствам.
© 2010–2020 Christian Johansen
Licensed under the BSD License.
https://sinonjs.org/releases/v9.2.2/stubs