Как получить разные возвращаемые значения для нескольких вызовов шпиона Jasmine

101

Скажем, я шпионю за таким методом:

spyOn(util, "foo").andReturn(true);

Тестируемая функция вызывается util.fooнесколько раз.

Возможно ли, чтобы шпион вернулся trueв первый раз, но вернулся falseво второй раз? Или есть другой способ сделать это?

михаил
источник

Ответы:

164

Вы можете использовать spy.and.returnValues (как Jasmine 2.4).

например

describe("A spy, when configured to fake a series of return values", function() {
  beforeEach(function() {
    spyOn(util, "foo").and.returnValues(true, false);
  });

  it("when called multiple times returns the requested values in order", function() {
    expect(util.foo()).toBeTruthy();
    expect(util.foo()).toBeFalsy();
    expect(util.foo()).toBeUndefined();
  });
});

Есть кое-что, о чем вы должны быть осторожны, есть еще одна функция, returnValueбез которой похожее заклинание s, если вы используете это, жасмин не предупредит вас.

Океан
источник
21
+1: это отличная функция. Однако одно предупреждение - будьте осторожны, чтобы не забыть in .returnValues- две функции, очевидно, разные, но передача нескольких аргументов в .returnValueне вызывает ошибки. Я не хочу признавать, сколько времени я потратил зря из-за этого одного персонажа.
The DIMM Reaper
@TheDIMMReaper, Спасибо. Я говорю об этом сейчас.
Ocean
Для меня было важно сделать это в beforeEach, а не в тесте (it)
Ян
Разумеется, не нужно беспокоиться об орфографических ошибках при использовании жасмина в TypeScript.
Warlike Chimpanzee
27

Для более старых версий Jasmine вы можете использовать spy.andCallFakeдля Jasmine 1.3 или spy.and.callFakeдля Jasmine 2.0, и вам нужно будет отслеживать состояние «вызываемого» либо с помощью простого закрытия, либо с помощью свойства объекта и т. Д.

var alreadyCalled = false;
spyOn(util, "foo").andCallFake(function() {
    if (alreadyCalled) return false;
    alreadyCalled = true;
    return true;
});
Войтос
источник
4
Мы можем расширить это действие более чем на 2 вызова, например: var results = [true, false, "foo"]; var callCount = 0; spyOn (util, "foo"). and.callFake (function () {вернуть результаты [callCount ++];});
Джек
1
Это может быть расширено до общей функции, например: function returnValues ​​() {var args = arguments; var callCount = 0; функция возврата () {аргументы возврата [callCount ++]; }; }
Tomas Lieberkind
Зачем нужен весь этот код, если можно просто вернуть results.shift ()?
ThaFog
как насчет того, когда мы вернемся к наблюдениям
Лиджо
этот вариант более гибкий, так как мы можем выдать ошибку или вернуть значение в зависимости от порядка вызова.
0bj3ct