Cómo tener diferentes valores de retorno para múltiples llamadas en un espía Jasmine

100

Digamos que estoy espiando un método como este:

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

La función bajo prueba llama util.foovarias veces.

¿Es posible que el espía regrese truela primera vez que se le llame, pero regrese falsela segunda vez? ¿O hay una forma diferente de hacerlo?

Mikhail
fuente

Respuestas:

163

Puede utilizar spy.and.returnValues (como Jasmine 2.4).

por ejemplo

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

No es algo que usted debe tener cuidado, hay otra función hechizo similares returnValuesin s, si se utiliza que, jazmín no advertirle.

Oceano
fuente
20
+1: esta es una característica excelente. Sin embargo, una advertencia: tenga cuidado de no olvidar la 's' en .returnValues: las dos funciones son obviamente diferentes, pero pasar múltiples argumentos a .returnValueno arroja un error. No quiero admitir cuánto tiempo perdí debido a ese personaje.
The DIMM Reaper
@TheDIMMReaper, gracias. Lo menciono ahora.
Océano
Hacerlo en el antes Cada uno era importante para mí, no en la prueba (eso)
Ian
No hay necesidad de preocuparse por los errores ortográficos al usar jazmín en TypeScript, por supuesto.
Chimpancé belicoso
27

Para versiones anteriores de Jasmine, puede usar spy.andCallFakeJasmine 1.3 o spy.and.callFakeJasmine 2.0, y tendrá que realizar un seguimiento del estado 'llamado', ya sea a través de un cierre simple o propiedad de objeto, etc.

var alreadyCalled = false;
spyOn(util, "foo").andCallFake(function() {
    if (alreadyCalled) return false;
    alreadyCalled = true;
    return true;
});
voithos
fuente
4
Podemos extender esto para más de 2 llamadas así: var results = [true, false, "foo"]; var callCount = 0; spyOn (util, "foo"). and.callFake (function () {return results [callCount ++];});
Jack
1
Esto puede extenderse a una función genérica como la siguiente: function returnValues ​​() {var args = argumentos; var callCount = 0; return function () {return args [callCount ++]; }; }
Tomas Lieberkind
¿Por qué todo este código cuando solo puede devolver results.shift ()?
ThaFog
¿Qué tal cuando regresemos observabvles
Lijo
esta opción es más flexible, ya que podemos lanzar un error o devolver un valor dependiendo del orden de la llamada.
0bj3ct