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