Spec-Zone.ru › Sinon.JS 9

Шпионы

Введение

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

Шпион для тестирования — это функция, которая записывает аргументы, возвращаемое значение, значение 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 булева свойство, а также 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
имя шпиона "spy" по умолчанию
%c
количество вызовов шпиона в словах ("один раз", "дважды" и т.д.)
%C
список строковых представлений вызовов шпиона, каждый вызов с префиксом новой строки и четырьмя пробелами
%t
список значений this, на которых был вызван шпион, через запятую
%n
отформатированное значение n-го аргумента, переданного в printf
%*
список аргументов (кроме строки формата) передаваемых в printf, через запятую
%D
многострочный список аргументов, полученных всеми вызовами шпиона

© 2010–2020 Christian Johansen
Licensed under the BSD License.
https://sinonjs.org/releases/v9.2.2/spies

Spec-Zone.ru

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