Заглушки
Что такое заглушки?
Тестовые заглушки — это функции (шпионы) с запрограммированным поведением.
Они поддерживают полный 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);
Заставляет заглушку возвращать обещания, используя определенную библиотеку обещаний вместо глобальной, когда используются 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, но с аргументами.
Асинхронные вызовы
То же самое, что и соответствующие им синхронные аналоги, но с отложенным обратным вызовом, вызываемым после обработки всех инструкций в текущем стеке вызовов.
- В среде 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
Содержит ссылку на исходный метод/функцию, которую эта подстановка обернула.
© 2010–2022 Christian Johansen
Licensed under the BSD License.
https://sinonjs.org/releases/v11/stubs