I want to write the unit test for the factory which have lot chain of promises. Below is my code snippet:
angular.module('myServices',[])
.factory( "myService",
['$q','someOtherService1', 'someOtherService2', 'someOtherService3', 'someOtherService4',
function($q, someOtherService1, someOtherService2, someOtherService3, someOtherService4) {
method1{
method2().then(
function(){ someOtherService3.method3();},
function(error){/*log error;*/}
);
return true;
};
var method2 = function(){
var defer = $q.defer();
var chainPromise = null;
angular.forEach(myObject,function(value, key){
if(chainPromise){
chainPromise = chainPromise.then(
function(){return method4(key, value.data);},
function(error){/*log error*/});
}else{
chainPromise = method4(key, value.data);
}
});
chainPromise.then(
function(){defer.resolve();},
function(error){defer.reject(error);}
);
return defer.promise;
};
function method4(arg1, arg2){
var defer = $q.defer();
someOtherService4.method5(
function(data) {defer.resolve();},
function(error) {defer.reject(error);},
[arg1,arg2]
);
return defer.promise;
};
var method6 = function(){
method1();
};
return{
method6:method6,
method4:method4
};
}]);
To test it, I have created spy object for all the services, but mentioning the problematic one
beforeEach( function() {
someOtherService4Spy = jasmine.createSpyObj('someOtherService4', ['method4']);
someOtherService4Spy.method4.andCallFake(
function(successCallback, errorCallback, data) {
// var deferred = $q.defer();
var error = function (errorCallback) { return error;}
var success = function (successCallback) {
deferred.resolve();
return success;
}
return { success: success, error: error};
}
);
module(function($provide) {
$provide.value('someOtherService4', someOtherService4);
});
inject( function(_myService_, $injector, _$rootScope_,_$q_){
myService = _myService_;
$q = _$q_;
$rootScope = _$rootScope_;
deferred = _$q_.defer();
});
});
it("test method6", function() {
myService.method6();
var expected = expected;
$rootScope.$digest();
expect(someOtherService3.method3.mostRecentCall.args[0]).toEqualXml(expected);
expect(someOtherService4Spy.method4).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), [arg,arg]);
expect(someOtherService4Spy.method4).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), [arg,arg]);
});
It is showing error on
expect(someOtherService3.method3.mostRecentCall.args[0]).toEqualXml(expected);
After debugging I found that it is not waiting for any promise to resolve, so method 1 return true, without even executing method3. I even tried with
someOtherService4Spy.method4.andReturn(function(){return deferred.promise;});
But result remain same. My question is do I need to resolve multiple times ie for each promise. How can I wait till all the promises are executed.