Spec-Zone.ru › Sinon.JS 14

Шпионы

Введение

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

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

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

Spec-Zone.ru

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