Jak mieć różne wartości zwracane dla wielu wywołań szpiega Jasmine

103

Powiedzmy, że szpieguję taką metodę:

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

Testowana funkcja wywołuje util.foowiele razy.

Czy jest możliwe, aby szpieg wrócił truepo pierwszym wywołaniu, ale wrócił falsepo raz drugi? A może można to zrobić w inny sposób?

mikhail
źródło

Odpowiedzi:

170

Możesz użyć spy.and.returnValues (jako Jasmine 2.4).

na przykład

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();
  });
});

Jest coś, na co musisz uważać, jest jeszcze jedna funkcja, returnValuebez której zaklęcie będzie podobne s, jeśli jej użyjesz, jaśmin cię nie ostrzeże.

Ocean
źródło
21
+1: to doskonała funkcja. Jednak słowo ostrzeżenia - uważaj, aby nie zapomnieć 's' in .returnValues- te dwie funkcje są oczywiście różne, ale przekazanie wielu argumentów do .returnValuenie powoduje błędu. Nie chcę się przyznać, ile czasu zmarnowałem z powodu tej jednej postaci.
The DIMM Reaper
@TheDIMMReaper, dziękuję. Wspominam o tym teraz.
Ocean
Robienie tego na początku Każdy był dla mnie ważny, a nie w teście (it)
Ian
Oczywiście nie musisz się martwić o błędy ortograficzne podczas używania jaśminu w TypeScript.
Warlike Chimpanzee
27

W przypadku starszych wersji Jasmine możesz użyć spy.andCallFakedla Jasmine 1.3 lub spy.and.callFakeJasmine 2.0 i będziesz musiał śledzić stan `` wywoływany '', albo poprzez proste zamknięcie, albo właściwość obiektu itp.

var alreadyCalled = false;
spyOn(util, "foo").andCallFake(function() {
    if (alreadyCalled) return false;
    alreadyCalled = true;
    return true;
});
voithos
źródło
4
Możemy rozszerzyć to na więcej niż 2 wywołania, w ten sposób: var results = [true, false, "foo"]; var callCount = 0; spyOn (util, "foo"). and.callFake (function () {return results [callCount ++];});
Jack
1
Można to rozszerzyć na funkcję ogólną, taką jak: function returnValues ​​() {var args = arguments; var callCount = 0; return function () {return args [callCount ++]; }; }
Tomas Lieberkind
Po co cały ten kod, skoro możesz po prostu zwrócić results.shift ()?
ThaFog
co powiesz na to, kiedy wrócimy do
wieży
ta opcja jest bardziej elastyczna, ponieważ możemy zgłosić błąd lub zwrócić wartość w zależności od kolejności wywołania.
0bj3ct