Any way to modify Jasmine spies based on arguments?
jasmine, javascript, unit-testing
Solution
In Jasmine versions 3.0 and above you can use `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);
});
});
For Jasmine versions earlier than 3.0 `callFake` is the right way to go, but you can simplify it using an object to hold the return values
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]
});
});
});
Depending on the version of Jasmine, the syntax is slightly different:
- 1.3.1: `.andCallFake(fn)`
- 2.0: `.and.callFake(fn)`
Resources:
- withArgs docs
- callFake docs
- andCallFake vs and.callFake
Problem
I have a function I'd like to test which calls an external API method twice, using different parameters. I'd like to mock this external API out with a Jasmine spy, and return different things based on the parameters. Is there any way to do this in Jasmine? The best I can come up with is a hack using 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; } }); }); }); ```