Comment avoir des valeurs de retour différentes pour plusieurs appels sur un espion Jasmine

100

Dites que j'espionne une méthode comme celle-ci:

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

La fonction testée appelle util.fooplusieurs fois.

Est-il possible que l'espion revienne truela première fois qu'il est appelé, mais revienne falsela deuxième fois? Ou y a-t-il une manière différente de procéder?

Mikhail
la source

Réponses:

163

Vous pouvez utiliser spy.and.returnValues (comme Jasmine 2.4).

par exemple

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

Il y a quelque chose dont vous devez faire attention, il y a une autre fonction qui sortira du même genre returnValuesans s, si vous l'utilisez, jasmin ne vous avertira pas.

Océan
la source
20
+1: c'est une excellente fonctionnalité. Un mot d'avertissement, cependant - attention à ne pas oublier le 's' in .returnValues- les deux fonctions sont évidemment différentes, mais passer plusieurs arguments à .returnValuene génère pas d'erreur. Je ne veux pas admettre combien de temps j'ai perdu à cause de ce seul personnage.
The DIMM Reaper
@TheDIMMReaper, merci. Je le mentionne maintenant.
Ocean
Le faire dans l'avantChaque était important pour moi, pas dans le test (it)
Ian
Pas besoin de s'inquiéter des fautes d'orthographe lors de l'utilisation de jasmine dans TypeScript, bien sûr.
Warlike Chimpanzee
27

Pour les anciennes versions de Jasmine, vous pouvez utiliser spy.andCallFakepour Jasmine 1.3 ou spy.and.callFakepour Jasmine 2.0, et vous devrez garder une trace de l'état `` appelé '', soit par une simple fermeture, soit par une propriété d'objet, etc.

var alreadyCalled = false;
spyOn(util, "foo").andCallFake(function() {
    if (alreadyCalled) return false;
    alreadyCalled = true;
    return true;
});
voithos
la source
4
Nous pouvons étendre cela pour plus de 2 appels comme ceci: var results = [true, false, "foo"]; var callCount = 0; spyOn (util, "foo"). and.callFake (function () {retourne les résultats [callCount ++];});
Jack
1
Cela peut être étendu dans une fonction générique comme ceci: function returnValues ​​() {var args = arguments; var callCount = 0; return function () {return args [callCount ++]; }; }
Tomas Lieberkind
Pourquoi tout ce code alors que vous pouvez simplement renvoyer results.shift ()?
ThaFog
Que
cette option est plus flexible, car nous pouvons lancer une erreur ou une valeur de retour en fonction de l'ordre d'appel.
0bj3ct