Spec-Zone.ru › Sinon.JS 12

Шпионы

Введение

Что такое шпион для тестирования?

Шпион для тестирования — это функция, которая записывает аргументы, возвращаемое значение, значение this и сгенерированное исключение (если таковое имеется) для всех своих вызовов. Существует два типа шпионов: некоторые — анонимные функции, а другие — обертки над методами, которые уже существуют в тестируемой системе.

Создание шпиона как анонимной функции

Когда поведение функции, над которой проводится наблюдение, не тестируется, вы можете использовать шпион-анонимную функцию. Шпион ничего не сделает, кроме как запишет информацию о своих вызовах. Общим случаем использования такого шпиона является тестирование того, как функция обрабатывает обратный вызов, как в следующем упрощенном примере:

Использование шпиона для обертывания всех методов объекта

sinon.spy(object)

Обертывает все методы объекта.

Обратите внимание, что обычно лучше шпионить за отдельными методами, особенно на объектах, которые вы не понимаете или не контролируете все методы (например, зависимости библиотек).

Шпионить за отдельными методами более точно проверяет намерения и менее подвержено неожиданному поведению по мере развития кода объекта.

Следующий пример несколько искусственный:

Использование шпиона для обертывания существующего метода

sinon.spy(object, "method") создаёт шпиона, который обертывает существующую функцию object.method. Шпион будет вести себя точно так же, как и исходный метод (включая использование в качестве конструктора), но вы получите доступ к данным обо всех вызовах. Следующий пример несколько искусственный:

Использование шпиона для обертывания свойств-геттеров и -сеттеров

sinon.spy(object, "property", ["get", "set"]) создаёт шпионов, которые обертывают геттеры и сеттеры для object.property. Шпионы будут вести себя точно так же, как исходные геттеры и сеттеры, но вы получите доступ к данным обо всех вызовах. Пример:

var object = {
  get test() {
    return this.property;
  },
  set test(value) {
    this.property = value * 2;
  },
};
var spy = sinon.spy(object, "test", ["get", "set"]);
object.test = 42;
assert(spy.set.calledOnce);
assert.equals(object.test, 84);
assert(spy.get.calledOnce);

Создание шпионов: sinon.spy() Подписи методов

var spy = sinon.spy();
Создаёт анонимную функцию, которая записывает аргументы, this значение, исключения и возвращаемые значения для всех вызовов.
var spy = sinon.spy(myFunc);
Оборачивает функцию шпионом. Вы можете передать этого шпиона там, где обычно передавалась исходная функция, чтобы проверить, как используется функция.
var spy = sinon.spy(object, "method");
Создаёт шпиона для object.method и заменяет исходный метод шпионом. Если свойство не является функцией, выбрасывается исключение. Шпион ведет себя точно так же, как исходный метод во всех случаях. Исходный метод можно восстановить, вызвав object.method.restore(). Возвращаемый шпион — это объект функции, заменивший исходный метод. spy === object.method.
var spy = sinon.spy(object, "property", types);
Создаёт шпиона для свойства object.property, которое заменяет дескриптор эквивалентным, где каждый указанный аксессор (параметр types) обернут как шпион. В отличие от обычных шпионов, возвращаемый объект — это дескриптор свойства, содержащий обернутые аксессоры (шпионы). Исходные аксессоры можно восстановить, вызвав spy.get.restore(), где get — это аксессор, который вы хотите восстановить.

API шпионов

Шпионы предоставляют богатый интерфейс для проверки их использования. В приведенных выше примерах показано свойство calledOnce boolean, метод getCall и свойство args возвращаемого объекта. Существует три способа проверки данных о вызовах.

Предпочтительный подход — использование метода calledWith шпиона (и его аналогов), так как это предотвращает излишнюю специфику ваших тестов относительно того, какой вызов что делал и так далее. Он вернёт true, если шпион был когда-либо вызван с предоставленными аргументами.

Если вам нужна специфичность, вы можете непосредственно проверить первый аргумент первого вызова. Существует два способа достижения этого:

В первом примере двумерный массив args используется непосредственно в шпионе, а во втором — извлекается первый объект вызова, а затем обращается к массиву args. Выбор зависит от предпочтений, но рекомендуемым подходом является использование spy.calledWith(arg1, arg2, ...), если нет необходимости в высокой специфичности тестов.

API

Объекты шпионов — это объекты, возвращаемые из sinon.spy(). При использовании шпионов для существующих методов с sinon.spy(object, method), следующие свойства и методы также доступны для object.method.

Свойства

spy.withArgs(arg1[, arg2, ...]);

Создаёт шпиона, который записывает вызовы только тогда, когда полученные аргументы совпадают с аргументами, переданными в withArgs. Это полезно для более выразительных утверждений, где вы можете получить доступ к шпиону с тем же вызовом.

Использует глубокое сравнение для объектов и массивов. Используйте spy.withArgs(sinon.match.same(obj)) для строгого сравнения (см. совпадения).

spy.callCount

Количество записанных вызовов.

spy.called

true если шпион был вызван хотя бы один раз

spy.notCalled

true если шпион не был вызван

spy.calledOnce

true если шпион был вызван ровно один раз

spy.calledTwice

true если шпион был вызван ровно два раза

spy.calledThrice

true если шпион был вызван ровно три раза

spy.firstCall

Первый вызов

spy.secondCall

Второй вызов

spy.thirdCall

Третий вызов

spy.lastCall

Последний вызов

spy.calledBefore(anotherSpy);

Возвращает true, если шпион был вызван до anotherSpy

spy.calledAfter(anotherSpy);

Возвращает true, если шпион был вызван после anotherSpy

spy.calledImmediatelyBefore(anotherSpy);

Возвращает true, если spy был вызван до anotherSpy, и никаких вызовов шпиона не произошло между spy и anotherSpy.

spy.calledImmediatelyAfter(anotherSpy);

Возвращает true, если spy был вызван после anotherSpy, и никаких вызовов шпиона не произошло между anotherSpy и spy.

spy.calledOn(obj);

Возвращает true, если шпион был вызван как минимум один раз с obj в качестве this. calledOn также принимает совпадение spyCall.calledOn(sinon.match(fn)) (см. совпадения).

spy.alwaysCalledOn(obj);

Возвращает true, если шпион всегда вызывался с obj в качестве this.

spy.calledWith(arg1, arg2, ...);

Возвращает true, если шпион был вызван как минимум один раз с указанными аргументами.

Может использоваться для частичного соответствия, Sinon проверяет только предоставленные аргументы по отношению к фактическим аргументам, поэтому вызов, который принял предоставленные аргументы (в тех же местах) и, возможно, другие тоже, вернёт true.

spy.calledOnceWith(arg1, arg2, ...);

Возвращает true, если шпион был вызван ровно один раз в целом, и этот один вызов использовал указанные аргументы.

spy.alwaysCalledWith(arg1, arg2, ...);

Возвращает true, если шпион всегда вызывался с указанными аргументами (и, возможно, другими).

spy.calledWithExactly(arg1, arg2, ...);

Возвращает true, если шпион был вызван как минимум один раз с указанными аргументами и никакими другими.

spy.calledOnceWithExactly(arg1, arg2, ...);

Возвращает true, если шпион был вызван ровно один раз в целом, и этот один вызов использовал именно указанные аргументы и никакие другие.

spy.alwaysCalledWithExactly(arg1, arg2, ...);

Возвращает true, если шпион всегда вызывался с указанными аргументами.

spy.calledWithMatch(arg1, arg2, ...);

Возвращает true, если шпион был вызван с соответствующими аргументами (и, возможно, другими).

Это работает так же, как spy.calledWith(sinon.match(arg1), sinon.match(arg2), ...).

spy.alwaysCalledWithMatch(arg1, arg2, ...);

Возвращает true, если шпион всегда вызывался с соответствующими аргументами (и, возможно, другими).

Это работает так же, как spy.alwaysCalledWith(sinon.match(arg1), sinon.match(arg2), ...).

spy.calledWithNew();

Возвращает true, если шпион/заглушка был вызван с оператором new.

Обратите внимание, что это определяется на основе значения объекта this и функции шпиона prototype, поэтому это может давать ложноположительные результаты, если вы активно возвращаете нужный тип объекта.

spy.neverCalledWith(arg1, arg2, ...);

Возвращает true, если шпион/заглушка никогда не вызывался с указанными аргументами.

spy.neverCalledWithMatch(arg1, arg2, ...);

Возвращает true, если шпион/заглушка никогда не вызывался с соответствующими аргументами.

Это работает так же, как spy.neverCalledWith(sinon.match(arg1), sinon.match(arg2), ...).

spy.threw();

Возвращает true, если шпион бросил исключение хотя бы один раз.

spy.threw("TypeError");

Возвращает true, если шпион бросил исключение указанного типа хотя бы один раз.

spy.threw(obj);

Возвращает true, если шпион бросил указанный объект исключения хотя бы один раз.

spy.alwaysThrew();

Возвращает true, если шпион всегда выбрасывал исключение.

spy.alwaysThrew("TypeError");

Возвращает true, если шпион всегда выбрасывал исключение указанного типа.

spy.alwaysThrew(obj);

Возвращает true, если шпион всегда выбрасывал предоставленный объект исключения.

spy.returned(obj);

Возвращает true, если шпион вернул предоставленное значение как минимум один раз.

Использует глубокое сравнение для объектов и массивов. Используйте spy.returned(sinon.match.same(obj)) для строгого сравнения (см. совпадения).

spy.alwaysReturned(obj);

Возвращает true, если шпион всегда возвращал предоставленное значение.

var spyCall = spy.getCall(n);

Возвращает n-й вызов.

Если n отрицательно, возвращается n-й вызов с конца. Например, spy.getCall(-1) возвращает последний вызов, а spy.getCall(-2) — предпоследний.

Доступ к отдельным вызовам помогает более детально проверить поведение, когда шпион вызывается более одного раза.

var spyCalls = spy.getCalls();

Возвращает Array всех вызовов, записанных шпионом.

spy.thisValues

Массив объектов this, spy.thisValues[0] является объектом this для первого вызова.

spy.args

Массив полученных аргументов, spy.args[0] — массив аргументов, полученных при первом вызове.

spy.exceptions

Массив объектов исключений, брошенных при spy.exceptions[0] — исключение, брошенное при первом вызове.

Если вызов не вызвал ошибку, значение в позиции вызова в .exceptions будет undefined.

spy.returnValues

Массив возвращаемых значений, spy.returnValues[0] — возвращаемое значение первого вызова.

Если вызов не явно не вернул значение, значение в позиции вызова в .returnValues будет undefined.

spy.resetHistory();

Сбрасывает состояние шпиона.

spy.restore();

Заменяет шпиона оригинальным методом. Доступно только если шпион заменил существующий метод.

spy.printf("format string", [arg1, arg2, ...]);

Возвращает переданную строку формата с выполненными заменами:

%n
имя шпиона («шпион» по умолчанию)
%c
количество вызовов шпиона в словах («один раз», «дважды» и т. д.)
%C
список строковых представлений вызовов шпиона, каждый вызов с префиксом из новой строки и четырёх пробелов
%t
список значений this через запятую, с которыми вызывался шпион
%n
отформатированное значение n-го аргумента, переданного методу printf
%*
список аргументов (кроме строки формата) через запятую, переданных методу printf
%D
многострочный список аргументов, полученных всеми вызовами шпиона

© 2010–2022 Christian Johansen
Licensed under the BSD License.
https://sinonjs.org/releases/v12/spies

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API