Заглушки
Что такое заглушки?
Заглушки — это функции (шпионы) с предопределённым поведением.
Они поддерживают полный 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); Добавлено в версии 1.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 «fluent».
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);
Заставляет заглушку возвращать промисы, используя определённую библиотеку 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/v10.0.1/stubs