Búsqueda de sitios web

javascript - ¿Alguna manera de modificar los spies de Jasmine según los argumentos?


Tengo una función que me gustaría probar, la cual llama a un método de API externo dos veces, usando diferentes parámetros. Me gustaría simular esta API externa con un spy de Jasmine, y devolver cosas diferentes según los parámetros. ¿Hay alguna manera de hacer esto en Jasmine? Lo mejor que se me ocurre es un truco usando andCallFake:

var functionToTest = function() {
  var userName = externalApi.get('abc');
  var userId = externalApi.get('123');
};


describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').andCallFake(function(myParam) {
      if (myParam == 'abc') {
        return 'Jane';
      } else if (myParam == '123') {
        return 98765;
      }
    });
  });
});

Respuesta #1

En las versiones 3.0 y superiores de Jasmine, puedes usar withArgs

describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get')
      .withArgs('abc').and.returnValue('Jane')
      .withArgs('123').and.returnValue(98765);
  });
});

Para las versiones de Jasmine anteriores a la 3.0, callFake es la forma correcta de proceder, pero puedes simplificarlo usando un objeto para contener los valores de retorno

describe('my fn', function() {
  var params = {
    'abc': 'Jane', 
    '123': 98765
  }

  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').and.callFake(function(myParam) {
     return params[myParam]
    });
  });
});

Dependiendo de la versión de Jasmine, la sintaxis es ligeramente diferente:

  • 1.3.1: .andCallFake(fn)
  • 2.0: .and.callFake(fn)

Recursos:

  • documentos conArgs
  • documentos callFake
  • andCallFake vs and.callFake

Respuesta #2

También podrías usar $provide para crear un espía. Y simular usando and.returnValues en lugar de and.returnValue para pasar datos parametrizados.

Según la documentación de Jasmine: Al encadenar el espía con and.returnValues, todas las llamadas a la función devolverán valores específicos en orden hasta que se alcance el final de la lista de valores de retorno, momento en el cual devolverá undefined para todas las llamadas posteriores.

describe('my fn', () => {
    beforeEach(module($provide => {
        $provide.value('externalApi', jasmine.createSpyObj('externalApi', ['get']));
    }));

        it('get userName and Id', inject((externalApi) => {
            // Given
            externalApi.get.and.returnValues('abc','123');

            // When
            //insert your condition

            // Then
            // insert the expectation                
        }));
});

Artículos relacionados