Como ter valores de retorno diferentes para várias chamadas em um espião Jasmine


100

Digamos que eu esteja espionando um método como este:

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

A função em teste chama util.foovárias vezes.

É possível fazer o espião retornar truena primeira vez que é chamado, mas retornar falsena segunda vez? Ou existe uma maneira diferente de fazer isso?

Respostas:


163

Você pode usar spy.and.returnValues (como Jasmine 2.4).

por exemplo

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

Há uma coisa com a qual você deve ter cuidado, há outra função semelhante ao feitiço returnValuesem s, se você usá-la, o jasmim não irá avisá-lo.


20
+1: este é um excelente recurso. Porém, uma palavra de advertência - tome cuidado para não esquecer o 's' em .returnValues- as duas funções são obviamente diferentes, mas passar vários argumentos para .returnValuenão gera um erro. Não quero admitir quanto tempo perdi com aquele personagem.
— The DIMM Reaper

@TheDIMMReaper, obrigado. Eu mencionei isso agora.
— Ocean

Fazer no beforeEach foi importante para mim, não no teste (it)
— Ian

Não há necessidade de se preocupar com erros de ortografia ao usar jasmine no TypeScript, é claro.
— Warlike Chimpanzee

27

Para versões mais antigas do Jasmine, você pode usar spy.andCallFakepara Jasmine 1.3 ou spy.and.callFakepara Jasmine 2.0, e você terá que controlar o estado 'chamado', seja por meio de um fechamento simples ou propriedade de objeto, etc.

var alreadyCalled = false;
spyOn(util, "foo").andCallFake(function() {
    if (alreadyCalled) return false;
    alreadyCalled = true;
    return true;
});

4
Podemos estender isso para mais de 2 chamadas da seguinte forma: var results = [true, false, "foo"]; var callCount = 0; spyOn (util, "foo"). and.callFake (function () {resultados de retorno [callCount ++];});
— Jack

1
Isso pode ser estendido para uma função genérica como: function returnValues ​​() {var args = arguments; var callCount = 0; return function () {return args [callCount ++]; }; }
— Tomas Lieberkind

Por que todo esse código quando você pode apenas retornar results.shift ()?
— ThaFog

e quando voltarmos observabvles
— Lijo

esta opção é mais flexível, pois podemos lançar um erro ou valor de retorno dependendo da ordem da chamada.
— 0bj3ct
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.