Testing promises with Jasmine
We have been using Jasmine to test our angular code. Recently I came across a piece of code in Javascript which included a REST API call and returned a promise. The promise then had a success callback and all the rest of the play. So in this blog, I have tried to illustrate how to test a promise.
Here I have a function which returns a promise and has a success handler and failure handler. So let’s see how to test such a function:
[js]
myFactory.getCallStatus = function() {
MyApi.getData().$promise.then(function(data) {
switch (data.status) {
case ‘UPDATED’:
myFactory.afterUpdate()
break;
case ‘COMPLETED’:
myFactory.afterCompleted();
break;
case ‘FAILED’:
myFactory.afterFailure()
break;
}
});
}
myFactory.afterUpdate=function(){
…
//some code here….
…
}
myFactory.afterCompleted=function(){
…
//some code here….
…
}
myFactory.afterFailure=function(){
…
//some code here….
…
}
[/js]
To start testing this, create a new file named “myFactory.test.js” and initialize the factory you need to test, which in this case is “MyFactory”.
[js]
‘use strict’;
describe(‘MyFactory’, function () {
var factory, $q, MyApi; // declare variables to hold reference of factory and $q service.
beforeEach(function() {
module(‘someModule’); // initialized module to which your factory belongs.
module(function ($provide) {
// resolve all required dependencies of factory.
$provide.factory(‘XYZFactory’, function() {});
})
inject(function (_MyFactory_, _$q_, _MyApi_) {
factory = _MyFactory_; // inject factory for which you are writting test cases.
$q = _$q_; // As we need $q service to test function which returns promise.
MyApi=_MyApi_;
});
});
describe(‘Validate getCallStatus’, function () {
var deferred;
var data = {‘status’:"UPDATED",info:’success’};
//Mocked data to resolve getData() call of MyApi .
it("Validate getCallStatus call has been completed.",function() {
deferred = $q.defer();
spyOn(MyApi, ‘getData’).and.callFake(function () {
//Here we will don’t have mocked our getData() api call and now it returns an object of
//promise and it’s not been resolved.
return {$promise:deferred.promise, $resolve:false};
});
// Now we will resolve this promise with our stubbed data.
deferred.resolve(data);
expect(MyApi.getData).toHaveBeenCalled();
expect(factory.afterUpdate).toHaveBeenCalled();
});
});
});
[/js]
So that’s how we tested promise and it’s resolution. I hope this helps you in your testing.
Thanks.