Spec-Zone.ru › Sinon.JS 1

Заглушки

Что такое заглушки?

Тестовые заглушки — это функции (шпионы) с предварительно запрограммированным поведением.

Они поддерживают полный API для тестирования шпионов помимо методов, которые могут использоваться для изменения поведения заглушки.

В качестве шпионов, заглушки могут быть анонимными или оборачивать существующие функции. При обертывании существующей функции заглушкой, исходная функция не вызывается.

Когда использовать заглушки?

Используйте заглушку, когда хотите:

  1. Управлять поведением метода из теста, чтобы принудительно направить код по определенному пути. Примеры включают принуждение метода к сбрасыванию ошибки, чтобы протестировать обработку ошибок.

  2. Когда вы хотите предотвратить прямой вызов определенного метода (возможно, потому что он вызывает нежелательное поведение, например, XMLHttpRequest или подобное).

Следующий пример — еще один тест из PubSubJS, который демонстрирует, как создать анонимную заглушку, которая выбрасывает исключение при вызове.

"test should call all subscribers, even if there are exceptions" : function(){
    var message = 'an example message';
    var stub = sinon.stub().throws();
    var spy1 = sinon.spy();
    var spy2 = sinon.spy();

    PubSub.subscribe(message, stub);
    PubSub.subscribe(message, spy1);
    PubSub.subscribe(message, spy2);

    PubSub.publishSync(message, undefined);

    assert(spy1.called);
    assert(spy2.called);
    assert(stub.calledBefore(spy1));
}

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

Определение поведения заглушки при последовательных вызовах

Вызов методов определения поведения, таких как 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);

Заменяет object.method на func, обернутую в spy.

Как обычно, object.method.restore(); можно использовать для восстановления исходного метода.

var stub = sinon.stub(obj);

Заглушает все методы объекта.

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

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

Если вы хотите создать объект-заглушку MyConstructor, но не хотите вызывать конструктор, используйте эту вспомогательную функцию.

var stub = sinon.createStubInstance(MyConstructor)

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

Заглушает метод только для указанных аргументов.

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

"test should stub method differently based on arguments": function () {
    var callback = sinon.stub();
    callback.withArgs(42).returns(1);
    callback.withArgs(1).throws("TypeError");

    callback(); // No return value, no exception
    callback(42); // Returns 1
    callback(1); // Throws TypeError
}

stub.onCall(n); Добавлена в v1.8

Определяет поведение заглушки при n-ом вызове. Полезно для тестирования последовательных взаимодействий.

"test should stub method differently on consecutive calls": function () {
    var callback = sinon.stub();
    callback.onCall(0).returns(1);
    callback.onCall(1).returns(2);
    callback.returns(3);

    callback(); // Returns 1
    callback(); // Returns 2
    callback(); // All following calls return 3
}

Есть методы onFirstCall, onSecondCall, onThirdCall для более естественного чтения определений заглушки.

onCall может комбинироваться со всеми методами определения поведения в этом разделе. В частности, его можно использовать вместе с withArgs.

"test should stub method differently on consecutive calls with certain argument": function () {
    var callback = sinon.stub();
    callback.withArgs(42)
        .onFirstCall().returns(1)
        .onSecondCall().returns(2);
    callback.returns(0);

    callback(1); // Returns 0
    callback(42); // Returns 1
    callback(1); // Returns 0
    callback(42); // Returns 2
    callback(1); // Returns 0
    callback(42); // Returns 0
}

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

stub.onFirstCall();

Псевдоним для stub.onCall(0);

stub.onSecondCall();

Псевдоним для stub.onCall(1);

stub.onThirdCall();

Псевдоним для stub.onCall(2);

stub.reset();

Сбрасывает историю заглушки, как при вызове spy.reset();

Примечание: Обновлено в sinon@2.0.0

stub.resetBehavior();

Сбрасывает поведение заглушки до стандартного поведения

var stub = sinon.stub();

stub.returns(54)

stub(); // 54

stub.resetBehavior();

stub(); // undefined

stub.returns(obj);

Заставляет заглушку возвращать предоставленное значение.

stub.returnsArg(index);

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

stub.returnsArg(0); заставляет заглушку возвращать первый аргумент.

stub.returnsThis();

Заставляет заглушку возвращать её this значение.

Полезно для заглушения API с флюентными вызовами, типа jQuery.

stub.throws();

Заставляет заглушку сбрасывать исключение (Error).

stub.throws("TypeError");

Заставляет заглушку сбрасывать исключение указанного типа.

stub.throws(obj);

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

stub.callsArg(index);

Заставляет заглушку вызвать аргумент по указанному индексу как функцию обратного вызова. stub.callsArg(0); заставляет заглушку вызвать первый аргумент как обратный вызов.

stub.callsArgOn(index, context);

Как stub.callsArg(index); но с дополнительным параметром для передачи контекста this.

stub.callsArgWith(index, arg1, arg2, ...);

Как callsArg, но с аргументами для передачи в обратный вызов.

stub.callsArgOnWith(index, context, arg1, arg2, ...);

Как выше, но с дополнительным параметром для передачи контекста this.

stub.yields([arg1, arg2, ...])

Аналогично callsArg.

Заставляет заглушку вызвать первый полученный обратный вызов с указанными аргументами (если таковые имеются).

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

stub.yieldsOn(context, [arg1, arg2, ...])

Как выше, но с дополнительным параметром для передачи контекста this.

stub.yieldsTo(property, [arg1, arg2, ...])

Заставляет шпиона вызвать обратный вызов, переданный как свойство объекта шпиону.

Как yields, yieldsTo получает первый соответствующий аргумент, находит обратный вызов и вызывает его с (необязательными) аргументами.

stub.yieldsToOn(property, context, [arg1, arg2, ...])

Как выше, но с дополнительным параметром для передачи контекста this.

"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.yield([arg1, arg2, ...])

Вызывает обратные вызовы, переданные в stub с заданными аргументами.

Если заглушка никогда не вызывалась с аргументом-функцией, yield выбросит ошибку.

Также переименован как invokeCallback.

stub.yieldTo(callback, [arg1, arg2, ...])

Вызывает обратные вызовы, переданные как свойство объекта заглушке.

Как yield, yieldTo получает первый соответствующий аргумент, находит обратный вызов и вызывает его с (необязательными) аргументами.

"calling callbacks": function () {
    var callback = sinon.stub();
    callback({
        "success": function () {
            console.log("Success!");
        },
        "failure": function () {
            console.log("Oh noes!");
        }
    });

    callback.yieldTo("failure"); // Logs "Oh noes!"
}

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, но с аргументами.

stub.callsArgAsync(index);

То же, что и соответствующие им не-асинхронные аналоги, но с отложенным обратным вызовом (выполнение не немедленно, а после короткой задержки и в другой «нити»)

stub.callsArgAsync(index);

stub.callsArgOnAsync(index, context);

stub.callsArgWithAsync(index, arg1, arg2, ...);

stub.callsArgOnWithAsync(index, context, arg1, arg2, ...);

stub.yieldsAsync([arg1, arg2, ...]);

stub.yieldsOnAsync(context, [arg1, arg2, ...]);

stub.yieldsToAsync(property, [arg1, arg2, ...]);

stub.yieldsToOnAsync(property, context, [arg1, arg2, ...])

То же, что и соответствующие им не-асинхронные аналоги, но с отложенным обратным вызовом (выполнение не немедленно, а после короткой задержки и в другой «нити»)

© 2010–2017 Christian Johansen
Licensed under the BSD License.
http://sinonjs.org/releases/v1.17.7/stubs

Spec-Zone.ru

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